Проблема с сборкой мусора в Java - PullRequest
1 голос
/ 11 февраля 2011

Итак, у меня есть это чрезвычайно интенсивное для памяти приложение Java, которое я создаю, которое создает дерево из миллионов узлов. Используя удобные полезные методы Runtime для получения информации о куче, я создал небольшой метод, который отображает текущее использование памяти, как показано ниже:

public void displayMemoryUsage() {
    long maxMem = Runtime.getRuntime().maxMemory();
    long freeMem = Runtime.getRuntime().freeMemory();
    long heapMem = Runtime.getRuntime().totalMemory();
    long usedMem = heapMem - freeMem;
    System.out.println("Memory used: " + (int) (usedMem * 100 / maxMem) + "%");
}

Итак, просто чтобы проверить это, я заставил дерево расширить свой корневой узел (до 2128 дочерних элементов), а затем расширил каждый из этих дочерних элементов (всего около 4 миллионов узлов в дереве). Память отображает 11% использованного. Затем я устанавливаю корень дерева как один из его дочерних элементов, и при этом удаляю все ссылки на другие дочерние элементы корня. Теоретически, это должно удалить 2127/2128 дочерних элементов исходного корня. Я запустил Java-метод Runtime.getRuntime (). Gc () для принудительной сборки мусора и сказал, чтобы он снова отображал использование памяти. На этот раз я получил 10%. Теоретически, должен ли этот новый процент не превышать 0,05% или 1/2128 от значения до установки нового корня?

Есть мысли, почему он не собирает мусор правильно?

Ответы [ 3 ]

4 голосов
/ 11 февраля 2011

Метод System.gc (и эквивалент Runtime.gc) является предложением сборщику мусора о том, что мусор следует собирать, так что это не настоящий способ "принудительного"сборщик мусора ":

Из спецификации API Java для метода System.gc:

Запускает сборщик мусора.

Вызов метода gc предполагаетчто виртуальная машина Java затрачивает усилия на переработку неиспользуемых объектов, чтобы сделать доступной память, которую они в настоящее время занимают, доступной для быстрого повторного использования. * Когда управление возвращается из вызова метода, виртуальная машина Java сделала все возможное, чтобы освободить пространство извсе выброшенные объекты.

(выделение добавлено.)

Кроме того, при небольшом техническом сборе, даже если сборка мусора все же имела место, имейте в виду, что есть и другиеобъекты, которые присутствуют на виртуальной машине Java, помимо вашей программы, поэтому из-за этого потребуются дополнительные ресурсы памяти.

Один ваЧтобы получить общее представление о том, сколько памяти занимает ваше дерево, нужно проверить использование памяти до и после создания вашего дерева - но учтите, что даже в этом случае во время работы вашего дерева может происходить сборка мусора.встроенный, так что даже это не будет идеальным показателем.

Вероятно, лучший вариант здесь - использовать профилировщик (такой как jvisualvm, который поставляется с JDK)на самом деле взглянуть на то, сколько кучи используется чем.

1 голос
/ 11 февраля 2011

Вместо этого вы должны попытаться профилировать свою заявку!

0 голосов
/ 11 февраля 2011
  1. Вы уверены, что нигде нет ссылок на удаленные узлы?
  2. Вы уверены, что долго ждали после gc (), т.е. предлагали ли вы это несколько раз?
...