проблема памяти статического хеш-карты Java - PullRequest
0 голосов
/ 30 июля 2009

У меня есть 2 класса, давайте назовем класс A и класс B.

public class A{
private static HashMap<String,B> isc= new HashMap<String,B>();

public static void UserDisconnected(String key){
    if(isc.containsKey(key)){
        if(isc.get(publicSID).timer != null){
            isc.get(key).timer.cancel();
            isc.get(key).timer=null;
        }
        isc.remove(key);
    }
    log.debug("isc size:" + isc.size());
}

//and other non-static variables and methods

}

public class B{
//contain no static variables and methods
public void startStream(){
    timer = new Timer();
    timer.schedule(new timedTask(), 0, interval);
}

public class timedTask extends TimerTask{
    public void run(){
        //do something
    }
}

Класс A будет работать в течение всего времени жизни приложения, в то время как экземпляры класса B, на которые ссылается хэш-карта (isc), находится в классе A. Проблема в том, что после того, как я запустил метод UserDisconnected () в классе A, я вижу, что размер isc равен 0, но использование памяти, как показано в диспетчере задач Windows Server 2008, возвращается вниз, не видит памяти быть освобожденным. Интересно, были ли собраны экземпляры класса B в хэш-карте? или они потерялись где-то там, где сборщик мусора даже не смог его собрать.

Спасибо.

Ответы [ 6 ]

2 голосов
/ 30 июля 2009

Одна вещь, которую вы должны знать, это то, что диспетчер задач Windows отображает память, выделенную вашей кучей Java JVM операционной системой. Число не увеличивается или уменьшается во время работы GC.

Возможно, вам следует попробовать WeakHashMap , если вы беспокоитесь о памяти и слишком долго зависаете над ссылками.

Я бы также рекомендовал использовать интерфейсную карту в качестве типа для isc.

2 голосов
/ 30 июля 2009

Не думаю, что вы ожидаете увидеть снижение использования памяти в диспетчере задач. Используемая память возвращается в Java для будущего использования, а не возвращается в ОС для других приложений.

1 голос
/ 30 июля 2009

Существует только один ответ:

профиль вашей заявки.

с одним из http://www.google.com/search?q=java+profile этих prfoilers вы точно знаете, когда и если какие-либо классы не очищаются после использования.

0 голосов
/ 31 июля 2009

Скачанные и использующие VisualVM сейчас, графики и диаграммы такие красивые ... Во всяком случае, я буду профилировать приложение, используя его. Большое спасибо, ребята.

0 голосов
/ 30 июля 2009

Как отмечали другие, JVM обычно не возвращает память, освобожденную GC, в ОС.

Чтобы увидеть соотношение между используемой и свободной памятью в JVM, используйте VisualVM , и вы также можете использовать его профилирование памяти (с помощью функции снимка кучи) для отслеживания причин утечки памяти.

JVM возвращает памяти в ОС, но ее настройки по умолчанию делают это очень неохотно, только когда у нее гораздо больше свободной памяти, чем используемой памяти. Вы можете настроить это поведение с помощью параметров -XX: MinHeapFreeRatio и -XX: MaxHeapFreeRatio .

0 голосов
/ 30 июля 2009

Вы не можете использовать диспетчер задач Windows, чтобы точно знать, сколько памяти использует ваша программа, потому что JVM все еще будет удерживать память, даже если никакие объекты не используют ее. Для JVM и его алгоритмов GC более эффективно резервировать больше памяти, чем на самом деле использует программа. Чтобы узнать фактическое использование памяти, вам нужен инструмент, такой как VisualVM (он также поставляется с последними JDK).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...