Hello,
It's quite intresting the nashorn implementation seems to have changed
significantly between java 8 and 9. In Java 8 I can not find any path to
root. Java 9 the objects are reported weakly reachable, or reachable
through jdk.internal.ref.CleanerImpl$PhantomCleanableRef. The resulting
behaviour is the same, the Objects will not be cleared. In my
environment I could run hundred's of gc, these Objects would not be
reclaimed. In my real world application these Objects would sometimes
get reclaimed after some unknown random actions (Executing other
Scripts, creating new NashornScriptEngines)
I supsect these weak references are just a diversion, the gc thinks
there is a strong chain to the LiveItems, but the chain doesn't get
exported in the snapshot.
Best regards,
Thorsten
Am 28.02.17 um 18:56 schrieb Poonam Bajaj Parhar:
Hello Thorsten,
I ran this test program with jdk9-ea and created a Heap Dump after the
first Full GC using -XX:+HeapDumpAfterFullGC. In that heap dump, I can
see 2 instances of LeakImpl:
Class Name | Objects | Shallow Heap | Retained Heap
----------------------------------------------------------
LeakDemo$LeakImpl| 2 | 32 |
----------------------------------------------------------
the first one is reachable as a local variable from the main thread
which is fine:
Class Name | Ref. Objects | Shallow
Heap | Ref. Shallow Heap | Retained Heap
----------------------------------------------------------------------------------------------------------------
java.lang.Thread @ 0x84f211f8 Thread | 1 |
120 | 16 | 736
'- <Java Local> LeakDemo$LeakImpl @ 0x850d89f0| 1 |
16 | 16 | 16
----------------------------------------------------------------------------------------------------------------
the other one is reachable through the referent
"jdk.nashorn.internal.objects.Global" of a WeakReference:
Class Name | Ref. Objects | Shallow Heap | Ref. Shallow
Heap | Retained Heap
-----------------------------------------------------------------------------------------------------------
class jdk.internal.loader.ClassLoaders @ 0x84f268f8 System
Class | 1 | 16
| 16 | 16
'- PLATFORM_LOADER jdk.internal.loader.ClassLoaders$PlatformClassLoader
@ 0x84f2a610 | 1 | 96
| 16 | 199,624
'- classes java.util.Vector @
0x850b2b70
| 1 | 32 | 16 | 68,104
'- elementData java.lang.Object[640] @
0x850b2b90 | 1
| 2,576 | 16 | 68,072
'- [196] class jdk.nashorn.internal.scripts.JD @
0x84f49960 | 1 | 8
| 16 | 4,560
'- map$ jdk.nashorn.internal.runtime.PropertyMap @
0x850d4a88 | 1 | 64
| 16 | 4,552
'- protoHistory java.util.WeakHashMap @
0x850d5418 | 1 |
48 | 16 | 2,208
'- table java.util.WeakHashMap$Entry[16] @
0x850d5448 | 1 | 80
| 16 | 2,112
*'- [10] java.util.WeakHashMap$Entry @
0x850d5498 | 1 | 40
| 16 | 2,032*
'- referent jdk.nashorn.internal.objects.Global
@ 0x85137a18 | 1 | 544
| 16 | 39,920
'- initscontext
javax.script.SimpleScriptContext @ 0x8515c910 | 1
| 32 | 16 | 280
'- engineScope LeakDemo$SimplestBindings @
0x8515c930 | 1 | 16
| 16 | 248
'- map java.util.HashMap @
0x8515c940 | 1 | 48
| 16 | 232
'- table java.util.HashMap$Node[16]
@ 0x8515c970 | 1 | 80
| 16 | 184
'- [9] java.util.HashMap$Node @
0x8515c9f8 | 1 | 32
| 16 | 48
'- value
LeakDemo$SimplestBindings$$Lambda$118 @ 0x8515ca18| 1
| 16 | 16 | 16
'- arg$1 LeakDemo$LeakImpl
@ 0x8515c600 | 1 | 16
| 16 | 1,073,741,856
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
From the GC logs, the referent is present in an old region:
[2.044s][info ][gc,metaspace ] GC(6) Metaspace: 13522K->13518K(1062912K)
[2.047s][info ][gc,start ] GC(6) Heap Dump (after full gc)
Dumping heap to java_pid20428.hprof ...
Heap dump file created [1081050745 bytes in 25.084 secs]
[27.137s][info ][gc ] GC(6) Heap Dump (after full gc)
25089.382ms
[27.137s][info ][gc ] GC(6) Pause Full (Allocation
Failure) 1028M->1028M(1970M) 25171.038ms
Also:
[10.651s][trace][gc,region] GC(6) G1HR POST-COMPACTION(OLD)
[0x0000000085100000, 0x0000000085161f20, 0x0000000085200000]
This Full GC didn't discover this WeakReference and didn't clear its
referent. It needs to be investigated if it gets cleared and collected
in the subsequent GCs.
Thanks,
Poonam
On 2/28/2017 9:06 AM, Jenny Zhang wrote:
Thorsten
Thanks very much for the micro. I have update it to
https://bugs.openjdk.java.net/browse/JDK-8173594
Thanks
Jenny
On 2/28/2017 4:45 AM, Thorsten Goetzke wrote:
Hello,
Back in January i posted about Unreachable Objects not claimed by the
gc, i am finally able to produce a micro, see below. When I run the
class below using -Xmx4g and take a memory snaphsot (hprof or
yourkit, doesnt matter), I will see 2 LeakImpl Objects. These Objects
have no reported path to root, yet they won't be collected. If i
lower the heap space to -Xmx2g the Application throws
java.lang.OutOfMemoryError: Java heap space.
@Jenny Zhang should I create a new bugreport, or will you take care
of this?
Best Regards,
Thorsten Goetzke
package de.frei.demo;
import jdk.nashorn.api.scripting.NashornScriptEngine;
import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
import javax.script.CompiledScript;
import javax.script.ScriptException;
import javax.script.SimpleBindings;
import java.util.function.Function;
public final class LeakDemo {
private static NashornScriptEngine ENGINE =
getNashornScriptEngine();
private static CompiledScript SCRIPT;
public static void main(String[] args) throws Exception {
simulateLoad();
simulateLoad();
System.gc();
Thread.sleep(1000000);
}
private static void simulateLoad() throws ScriptException {
final CompiledScript compiledScript = getCompiledScript(ENGINE);
compiledScript.eval(new SimplestBindings(new LeakImpl()));
}
private static NashornScriptEngine getNashornScriptEngine() {
final NashornScriptEngineFactory factory = new
NashornScriptEngineFactory();
final NashornScriptEngine scriptEngine =
(NashornScriptEngine) factory.getScriptEngine();
return scriptEngine;
}
private static CompiledScript getCompiledScript(final
NashornScriptEngine scriptEngine) throws ScriptException {
if (SCRIPT == null) {
SCRIPT = scriptEngine.compile(" var pivot =
getItem(\"pivot\");");
}
return SCRIPT;
}
public interface Leak {
LiveItem getItem(String id);
}
public static final class LeakImpl implements Leak {
private final byte[] payload = new byte[1024 * 1024 * 1024];
@Override
public LiveItem getItem(final String id) {
return new LiveItem() {
};
}
}
public interface LiveItem {
}
public static final class SimplestBindings extends SimpleBindings {
public SimplestBindings(Leak leak) {
put("getItem",(Function< String, LiveItem>) leak::getItem);
}
}
}
_______________________________________________
hotspot-gc-use mailing list
hotspot-gc-use@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/hotspot-gc-use
_______________________________________________
hotspot-gc-use mailing list
hotspot-gc-use@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/hotspot-gc-use
_______________________________________________
hotspot-gc-use mailing list
hotspot-gc-use@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/hotspot-gc-use