Почему Java11 хранит java .util.zip.ZipFile $ Source в куче? - PullRequest
1 голос
/ 24 марта 2020

Может ли кто-нибудь помочь мне понять, является ли то, что я вижу, преднамеренным, правильным поведением или какой-то утечкой в ​​Java11? Давайте возьмем глупое простое приложение hello world:

package com.example;

public class HelloWorld {
    public static void main(String[] args) throws InterruptedException {
        for( int i =0 ; i < 50; i++){
            Thread.sleep(1000);
            System.out.println("hello " + i);
        }
    }
}

Единственная интересная часть - это зависимость от jar. Это может быть любой jar-файл, но чтобы сделать проблему более впечатляющей, давайте используем большой jar-файл gwt, который весит 30 МБ:

plugins {
    id 'java'
}

group 'com.example'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    // https://mvnrepository.com/artifact/com.google.gwt/gwt-user
    compile group: 'com.google.gwt', name: 'gwt-user', version: '2.7.0'
}

Запустите приложение, откройте jvisualvm, создайте дамп и ищите сохраненный набор java.util.zip.ZipFile$Source:

jvisualvm heapdump

Этот jar-файл из classpath (фактически никогда не использовался) занимает 1,5 МБ кучи. Он не go исчезает во время G C, он не go удаляется, когда вам не хватает памяти, я даже видел эти записи в heapdumps OutOfMemory.

Запись, очевидно, хранится на карте java.util.zip.ZipFile$Source.files. Из источника я могу сказать, что это теоретически должно быть очищено потоком Common-Cleaner из InnocuousThreadGroup, но я не вижу, чтобы это происходило.

Я столкнулся с этой проблемой при переносе небольшого, легкого Java приложения из JDK8 в JDK11. При низких настройках Xmx эти банки занимают значительную часть моей кучи по сравнению с JDK8.

Так это ошибка или особенность?

1 Ответ

1 голос
/ 27 марта 2020

Это намеренно.

Наблюдение о том, что использование памяти, по-видимому, увеличивается, вызвано переходом от нативной к чистой реализации на основе java [1] для файлов zip / jar в JDK 9. В основном для Цели стабильности.

Я отмечу, что собственная реализация выделяет структуры данных схожего и одинакового размера, но они были скрыты из-за инструментов, проверяющих кучу java.

Но даже если общий объем памяти должен быть более или менее нейтральным, может потребоваться увеличение размера кучи java, чтобы охватить увеличение использования кучи java.

[1 ] https://bugs.openjdk.java.net/browse/JDK-8145260

...