tikinghu / google-collections

Automatically exported from code.google.com/p/google-collections
0 stars 0 forks source link

MemoryLeak(?) when using expiration in MapMaker #308

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Expected: Using "public MapMaker expiration(long duration, TimeUnit unit)" 
should not 
influence garbage collection.

Observed: In one of my junit tests, test case A asserts that an 
OutOfMemoryError is thrown 
under special circumstances when MapMaker and expiration are used. Test case B, 
which is 
executed after A and does something different with a new map instance, 
unexpectedly fails 
with OOME. This means the memory allocated in test case A was not released, 
even though no 
fields are used and an new map instance is created. If expiration is not used, 
all works as 
expected.

I tried to reproduce the same effect in a smaller test case, but did not 
succeed. Instead 
expecting an OOME already fails (with an OOME). Looking at the stacktrace, the 
junit code 
executed after a test, runs into an OOME (which also indicates, that the memory 
allocated 
in the test is not released).

Stacktrace:
java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOfRange(Arrays.java:3209)
    at java.lang.String.<init>(String.java:216)
    at java.lang.StringBuilder.toString(StringBuilder.java:430)
    at java.net.URLStreamHandler.parseURL(URLStreamHandler.java:232)
    at sun.net.www.protocol.file.Handler.parseURL(Handler.java:50)
    at java.net.URL.<init>(URL.java:596)
    at java.net.URL.<init>(URL.java:464)
    at sun.misc.URLClassPath$FileLoader.getResource(URLClassPath.java:973)
    at sun.misc.URLClassPath.getResource(URLClassPath.java:168)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:192)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
    at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
    at 
org.junit.internal.runners.model.EachTestNotifier.addFailure(EachTestNotifier.ja
va:29)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:226)
    at 
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReferen
ce.java:46)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at 
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner
.java:467)
    at 
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner
.java:683)
    at 
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java
:390)
    at 
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.jav
a:197)

Original issue reported on code.google.com by woid...@gmail.com on 14 Dec 2009 at 3:30

Attachments:

GoogleCodeExporter commented 9 years ago
This also seems to destroy the semantic of weakValues().

To reproduce:

1. Remove "(expected = OutOfMemoryError.class)" from the test case.

2.a. remove expiration() and and add weakValues()
  ConcurrentMap<String, String> map = new MapMaker().weakValues().makeMap();
Observed: Works, no OOME.

2.b. Leave expiration() in place and add weakValues()
  ConcurrentMap<String, String> map = new MapMaker().weakValues().expiration(3600, 
TimeUnit.SECONDS).makeMap();
Observed: OOME (even though weakValues() was used!) What is more the number of 
entries that 
can be stored in this way does not differ much from not using weakValues() at 
all. In my test 
the combination weakValues/expiration adds ~ 550K while a normal "new 
MapMaker().makeMap()"-
map adds ~ 450K.

Original comment by woid...@gmail.com on 14 Dec 2009 at 3:46

GoogleCodeExporter commented 9 years ago
This issue has been moved to the Guava project (keeping the same id number). 
Simply replace 'google-collections' with 'guava-libraries' in your address 
bar and it should take you there.

Original comment by kevinb@google.com on 5 Jan 2010 at 11:09