Утечка памяти Java: почему недоступные объекты не собираются?

Я пытаюсь найти обходной путь для ошибки JDK Nashorn JDK-8229011.

Я воспроизвел ошибку с помощью скрипта, указанного в сообщении об ошибке, и сделал несколько дампов кучи. Я использовал JProfiler и Eclipse Memory Analyzer, чтобы найти корень проблемы. Но я всегда оказываюсь на недоступных путях и не понимаю, почему объекты не собираются мусором. AFAIS нет никаких финализаторов, чтобы сохранить их живыми. Если я открою дамп кучи в JProfiler, не отключив полный сборщик мусора для дампа, JProfiler даже выбросит недостижимые объекты. Но сам GC не будет. Я тестировал G1 GC, но то же самое и с CMS.

Образец дампа можно получить за 1-2 минуты с любым JDK › 8, запустив следующий скрипт с настройками: -Xmx20M -XX:+HeapDumpOnOutOfMemoryError

public class TestJsMemLeak
{
    public static final class JsJavaUtil
    {
        private long counter = 0;

        public long testFunc()
        {
            return counter++;
        }
    }

    public static void main(final String[] args) throws Exception
    {
        System.setProperty("nashorn.args", "--no-java -doe -ot=false --language=es6 --no-deprecation-warning --lazy-compilation=false");       
        for (long i = 0; true; ++i)
        {
            final ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName("nashorn");
            scriptEngine.put("JsJavaUtil", new JsJavaUtil());
            scriptEngine.eval("for (var i = 0; i < 10; ++i) {\n" + " JsJavaUtil.testFunc();\n" + "}");
            System.gc();
            if (i % 100 == 0)
            {
                System.out.println(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
            }
        }
    }
}

Запуск этого приведет к дампу с недоступным java.lang.ClassValue$ClassValueMap размером около 6-7 МБ.

Я ищу подсказки, что поддерживает жизнь этих объектов.


person Lukas Stampf    schedule 26.06.2020    source источник


Ответы (1)


Я не знаю, что происходит, но последняя сборка Eclipse Memory Analyzer дает интересные выводы. Сравнение моментальных снимков — загрузка дампа кучи 1, загрузка дампа кучи 2, запуск подозрительных утечек путем сравнения снимков: включает подозрительные утечки и обзор системы из сравнения двух снимков.

Подозреваемый в проблеме 1

Один загруженный экземпляр java.lang.ClassValue$ClassValueMap занимает +809 280 (19,48%) байт. Память аккумулируется в одном экземпляре java.lang.ClassValue$ClassValueMap, загруженном , который занимает +809 280 (19,48%) байт.

Ключевые слова java.lang.ClassValue$ClassValueMap

Также в отчете о компонентах говорится:

Слабая справочная статистика

Всего было найдено 10 007 объектов java.lang.ref.WeakReference, которые слабо ссылаются на 6 969 объектов. 6 объектов общим объемом 192 Б сохраняются (поддерживаются) только через слабые ссылки. Возможная утечка памяти 5785 объектов общим объемом 124,4 КБ имеют слабые ссылки, а также сильно сохраняются (поддерживаются) посредством слабых ссылок.

Подробности "

person user13762112    schedule 15.10.2020