Утечка памяти в объектах java.lang.ref.WeakReference внутри классов JDK - PullRequest
6 голосов
/ 23 марта 2010

Следующий простой код воспроизводит рост java.lang.ref.WeakReference объектов в куче:

public static void main(String[] args) throws Exception {

while (true) {
java.util.logging.Logger.getAnonymousLogger();
Thread.sleep(1);
}
}

Вот вывод команды jmap с интервалом в несколько секунд:

user@t1007:~> jmap -d64 -histo:live 29201|grep WeakReference
8: 22493 1079664 java.lang.ref.WeakReference
31: 1 32144 [Ljava.lang.ref.WeakReference;
106: 17 952

com.sun.jmx.mbeanserver.WeakIdentityHashMap$IdentityWeakReference
user@t1007:~> jmap -d64 -histo:live 29201|grep WeakReference
8: 23191 1113168 java.lang.ref.WeakReference
31: 1 32144 [Ljava.lang.ref.WeakReference;
103: 17 952

com.sun.jmx.mbeanserver.WeakIdentityHashMap$IdentityWeakReference
user@t1007:~> jmap -d64 -histo:live 29201|grep WeakReference
8: 23804 1142592 java.lang.ref.WeakReference
31: 1 32144 [Ljava.lang.ref.WeakReference;
103: 17 952 com.sun.jmx.mbeanserver.WeakIdentityHashMap$IdentityWeakReference

Обратите внимание, что команда jmap вызывает FullGC.

JVM settings:
export JVM_OPT="\
-d64 \
-Xms200m -Xmx200m \
-XX:MaxNewSize=64m \
-XX:NewSize=64m \
-XX:+UseParNewGC \
-XX:+UseConcMarkSweepGC \
-XX:MaxTenuringThreshold=10 \
-XX:SurvivorRatio=2 \
-XX:CMSInitiatingOccupancyFraction=60 \
-XX:+UseCMSInitiatingOccupancyOnly \
-XX:+CMSParallelRemarkEnabled \
-XX:+DisableExplicitGC \
-XX:+CMSClassUnloadingEnabled \
-XX:+PrintGCTimeStamps \
-XX:+PrintGCDetails \
-XX:+PrintTenuringDistribution \
-XX:+PrintGCApplicationConcurrentTime \
-XX:+PrintGCApplicationStoppedTime \
-XX:+PrintGCApplicationStoppedTime \
-XX:+PrintClassHistogram \
-XX:+ParallelRefProcEnabled \
-XX:SoftRefLRUPolicyMSPerMB=1 \
-verbose:gc \
-Xloggc:$GCLOGFILE"

java version "1.6.0_18"
Java(TM) SE Runtime Environment (build 1.6.0_18-b07)
Java HotSpot(TM) Server VM (build 16.0-b13, mixed mode)

Solaris 10/Sun Fire(TM) T1000 

Ответы [ 5 ]

5 голосов
/ 11 января 2012

Исправлено в 1.6.0_29: http://www.oracle.com/technetwork/java/javase/6u29-relnotes-507960.html?ssSourceSiteId=ocomen

1.6.0_29 не упоминается на самой странице ошибки (http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6942989), поэтому я подумал, что было бы полезно опубликовать ссылкутак что факт, что это было исправлено, можно обнаружить.

4 голосов
/ 08 ноября 2010

Кажется, это будет исправлено в JDK 7. При http://bugs.sun.com/view_bug.do?bug_id=6942989 написано: Release Fixed 7 (b102)

4 голосов
/ 04 мая 2010

Я воспроизвел это на 1.6.0_19.

Если вы запустите образец приложения с такими аргументами java:

-Xms8m -Xmx8m -XX: MaxPermSize = 8m

Через 10–15 минут он выдаст ошибку OutOfMemoryError.

Я отправил сообщение об ошибке в Sun.Они своевременно сообщат мне, если это будет принято.

0 голосов
/ 28 мая 2010

Sun приняла эту ошибку в своем трекере, но по какой-то причине она не отображается на их сайте, поэтому я не могу опубликовать ссылку здесь (пока).Говоря с Солнцем прямо сейчас, чтобы спросить их, что случилось.

0 голосов
/ 22 апреля 2010

Подтверждено в JDK 1.6.0_19 и 1.6.0_20, отсутствует в 1.6.0_17:

Java-версия "1.6.0_17" Java (TM) SE Runtime Environment (сборка 1.6.0_17-b04) Java HotSpot(TM) Виртуальная машина сервера (сборка 14.3-b01, смешанный режим)

Утечка ссылок накапливается в массиве java.util.logging.Logger # kids, но, скорее всего, изменения в LogManager вызвали это.

...