Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory leak of java.lang.ref.WeakReference objects inside JDK classes

The following simple code reproduces the growth of java.lang.ref.WeakReference objects in the heap:

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

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

Here is the output of jmap command within a few seconds interval:

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

Note that jmap command forces 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 
like image 258
mandye Avatar asked Mar 23 '10 05:03

mandye


People also ask

How do you fix a memory leak in Java?

Use reference objects to avoid memory leaks Using the java. lang. ref package, you can work with the garbage collector in your program. This allows you to avoid directly referencing objects and use special reference objects that the garbage collector easily clears.

Which of the following is true about memory leak in Java?

A Memory Leak is a situation where there are objects present in the heap that are no longer used, but the garbage collector is unable to remove them from memory, and therefore, they're unnecessarily maintained. A memory leak is bad because it blocks memory resources and degrades system performance over time.

How do you fix a memory leak?

The usual fix is to reboot. Freeing up the operating system for reuse of the space that has been taken over by memory leaks is called garbage collection. In the past, programs have had to explicitly request storage and then return it to the system when it was no longer needed.


2 Answers

Fixed in 1.6.0_29: http://www.oracle.com/technetwork/java/javase/6u29-relnotes-507960.html?ssSourceSiteId=ocomen

1.6.0_29 is not mentioned on the bug page itself ( http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6942989 ), so I thought it'd be useful to post the link there so the fact it's been fixed is discoverable.

like image 157
vt. Avatar answered Sep 22 '22 01:09

vt.


I have reproduced this on 1.6.0_19.

If you run the sample application with these java arguments:

-Xms8m -Xmx8m -XX:MaxPermSize=8m

After 10 - 15 minutes it will produce an OutOfMemoryError.

I have filed a bug report with Sun. They will let me know in due time if it has been accepted.

like image 45
Stijn de Witt Avatar answered Sep 19 '22 01:09

Stijn de Witt