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
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With