TestCleanupDetector
+ +|
+
+
+
|
+
+
+
+100%
+successful + |
+
-
+
- +Tests + +
Tests
+| Test | +Duration | +Result | +
|---|---|---|
| isPhantomRefCollectable() | +1.121s | +passed | +
| isRunnableCalled() | +0.017s | +passed | +
diff --git a/.gradle/8.8/checksums/checksums.lock b/.gradle/8.8/checksums/checksums.lock new file mode 100644 index 0000000..8366b71 Binary files /dev/null and b/.gradle/8.8/checksums/checksums.lock differ diff --git a/.gradle/8.8/checksums/md5-checksums.bin b/.gradle/8.8/checksums/md5-checksums.bin new file mode 100644 index 0000000..1eb722e Binary files /dev/null and b/.gradle/8.8/checksums/md5-checksums.bin differ diff --git a/.gradle/8.8/checksums/sha1-checksums.bin b/.gradle/8.8/checksums/sha1-checksums.bin new file mode 100644 index 0000000..ef7c9ab Binary files /dev/null and b/.gradle/8.8/checksums/sha1-checksums.bin differ diff --git a/.gradle/8.8/dependencies-accessors/gc.properties b/.gradle/8.8/dependencies-accessors/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/.gradle/8.8/executionHistory/executionHistory.bin b/.gradle/8.8/executionHistory/executionHistory.bin new file mode 100644 index 0000000..c67430e Binary files /dev/null and b/.gradle/8.8/executionHistory/executionHistory.bin differ diff --git a/.gradle/8.8/executionHistory/executionHistory.lock b/.gradle/8.8/executionHistory/executionHistory.lock new file mode 100644 index 0000000..a44f868 Binary files /dev/null and b/.gradle/8.8/executionHistory/executionHistory.lock differ diff --git a/.gradle/8.8/fileChanges/last-build.bin b/.gradle/8.8/fileChanges/last-build.bin new file mode 100644 index 0000000..f76dd23 Binary files /dev/null and b/.gradle/8.8/fileChanges/last-build.bin differ diff --git a/.gradle/8.8/fileHashes/fileHashes.bin b/.gradle/8.8/fileHashes/fileHashes.bin new file mode 100644 index 0000000..b9d646b Binary files /dev/null and b/.gradle/8.8/fileHashes/fileHashes.bin differ diff --git a/.gradle/8.8/fileHashes/fileHashes.lock b/.gradle/8.8/fileHashes/fileHashes.lock new file mode 100644 index 0000000..66fbee1 Binary files /dev/null and b/.gradle/8.8/fileHashes/fileHashes.lock differ diff --git a/.gradle/8.8/fileHashes/resourceHashesCache.bin b/.gradle/8.8/fileHashes/resourceHashesCache.bin new file mode 100644 index 0000000..8be149f Binary files /dev/null and b/.gradle/8.8/fileHashes/resourceHashesCache.bin differ diff --git a/.gradle/8.8/gc.properties b/.gradle/8.8/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock new file mode 100644 index 0000000..9c8137c Binary files /dev/null and b/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/.gradle/buildOutputCleanup/cache.properties b/.gradle/buildOutputCleanup/cache.properties new file mode 100644 index 0000000..7c1868f --- /dev/null +++ b/.gradle/buildOutputCleanup/cache.properties @@ -0,0 +1,2 @@ +#Sun Jun 14 15:45:41 CEST 2026 +gradle.version=8.8 diff --git a/.gradle/buildOutputCleanup/outputFiles.bin b/.gradle/buildOutputCleanup/outputFiles.bin new file mode 100644 index 0000000..ac1964e Binary files /dev/null and b/.gradle/buildOutputCleanup/outputFiles.bin differ diff --git a/.gradle/file-system.probe b/.gradle/file-system.probe new file mode 100644 index 0000000..d9ff95e Binary files /dev/null and b/.gradle/file-system.probe differ diff --git a/.gradle/vcs-1/gc.properties b/.gradle/vcs-1/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/.tmp/jmb-all.txt b/.tmp/jmb-all.txt new file mode 100644 index 0000000..2266e56 --- /dev/null +++ b/.tmp/jmb-all.txt @@ -0,0 +1,195 @@ +> Task :compileJava UP-TO-DATE +> Task :processResources NO-SOURCE +> Task :classes UP-TO-DATE +> Task :compileTestJava UP-TO-DATE +> Task :processTestResources NO-SOURCE +> Task :testClasses UP-TO-DATE + +> Task :test + +TestCleanupDetector > isRunnableCalled() PASSED + +TestCleanupDetector > isPhantomRefCollectable() PASSED + +TestJMemoryBuddy > testCreateHeapDump() STANDARD_OUT + Creating Heapdump at: /Users/floriankirmaier/projects/claude/JMemoryBuddy/build/heapdump_jmemb_2026-06-14_15-47-23.hprof + +TestJMemoryBuddy > testCreateHeapDump() PASSED + +TestJMemoryBuddy > simpleTest() PASSED + +TestJMemoryBuddy > simpleTest2() PASSED + +TestJMemoryBuddy > simpleTest3() PASSED + +TestJMemoryBuddy > multiHopPath() STANDARD_OUT + Creating Heapdump at: /Users/floriankirmaier/projects/claude/JMemoryBuddy/build/heapdump_jmemb_2026-06-14_15-47-25.hprof + + JMemoryBuddy — path to GC root for leak: Object @7e016b900: + GC root [Java frame] TestJMemoryBuddy$Holder + ↓ TestJMemoryBuddy$Holder.field + Object ← leaked + + multiHopPath message: The following references should be collected: [java.lang.Object@67d18ed7] + +TestJMemoryBuddy > multiHopPath() PASSED + +TestJMemoryBuddy > negativeTest2() STANDARD_OUT + Creating Heapdump at: /Users/floriankirmaier/projects/claude/JMemoryBuddy/build/heapdump_jmemb_2026-06-14_15-47-25.hprof + +TestJMemoryBuddy > negativeTest2() STANDARD_ERROR + java.io.IOException: File exists + at jdk.management/com.sun.management.internal.HotSpotDiagnostic.dumpHeap0(Native Method) + at jdk.management/com.sun.management.internal.HotSpotDiagnostic.dumpHeap(HotSpotDiagnostic.java:70) + at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) + at java.base/java.lang.reflect.Method.invoke(Method.java:580) + at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:64) + at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) + at java.base/java.lang.reflect.Method.invoke(Method.java:580) + at java.base/sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:97) + at java.management/com.sun.jmx.mbeanserver.ConvertingMethod.invokeWithOpenReturn(ConvertingMethod.java:193) + at java.management/com.sun.jmx.mbeanserver.ConvertingMethod.invokeWithOpenReturn(ConvertingMethod.java:175) + at java.management/com.sun.jmx.mbeanserver.MXBeanIntrospector.invokeM2(MXBeanIntrospector.java:115) + at java.management/com.sun.jmx.mbeanserver.MXBeanIntrospector.invokeM2(MXBeanIntrospector.java:52) + at java.management/com.sun.jmx.mbeanserver.MBeanIntrospector.invokeM(MBeanIntrospector.java:236) + at java.management/com.sun.jmx.mbeanserver.PerInterface.invoke(PerInterface.java:138) + at java.management/com.sun.jmx.mbeanserver.MBeanSupport.invoke(MBeanSupport.java:252) + at java.management/javax.management.StandardMBean.invoke(StandardMBean.java:405) + at java.management/com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:803) + at java.management/com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:802) + at java.management/com.sun.jmx.mbeanserver.MXBeanProxy$InvokeHandler.invoke(MXBeanProxy.java:150) + at java.management/com.sun.jmx.mbeanserver.MXBeanProxy.invoke(MXBeanProxy.java:167) + at java.management/javax.management.MBeanServerInvocationHandler.invoke(MBeanServerInvocationHandler.java:258) + at jdk.proxy2/jdk.proxy2.$Proxy12.dumpHeap(Unknown Source) + at one.jpro.jmemorybuddy.JMemoryBuddy.createHeapDump(JMemoryBuddy.java:212) + at one.jpro.jmemorybuddy.JMemoryBuddy.memoryTest(JMemoryBuddy.java:193) + at one.jpro.jmemorybuddy.TestJMemoryBuddy.negativeTest2(TestJMemoryBuddy.java:90) + at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) + at java.base/java.lang.reflect.Method.invoke(Method.java:580) + at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:767) + at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60) + at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131) + at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156) + at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147) + at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86) + at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103) + at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93) + at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106) + at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64) + at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45) + at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37) + at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92) + at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86) + at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$8(TestMethodTestDescriptor.java:217) + at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:213) + at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:138) + at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:156) + at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:146) + at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:144) + at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:143) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:100) + at java.base/java.util.ArrayList.forEach(ArrayList.java:1596) + at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:160) + at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:146) + at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:144) + at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:143) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:100) + at java.base/java.util.ArrayList.forEach(ArrayList.java:1596) + at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:160) + at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:146) + at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:144) + at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:143) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:100) + at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35) + at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) + at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54) + at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107) + at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88) + at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54) + at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67) + at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52) + at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114) + at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86) + at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86) + at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:119) + at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:94) + at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:89) + at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62) + at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) + at java.base/java.lang.reflect.Method.invoke(Method.java:580) + at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36) + at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) + at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33) + at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94) + at jdk.proxy1/jdk.proxy1.$Proxy2.stop(Unknown Source) + at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193) + at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129) + at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100) + at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60) + at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56) + at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:119) + at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:66) + at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69) + at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74) + +TestJMemoryBuddy > negativeTest2() STANDARD_OUT + The following references should not be collected: [[someText]] + +TestJMemoryBuddy > negativeTest2() PASSED + +TestJMemoryBuddy > testErrorMessages1() STANDARD_OUT + Creating Heapdump at: /Users/floriankirmaier/projects/claude/JMemoryBuddy/build/heapdump_jmemb_2026-06-14_15-47-26.hprof + JMemoryBuddy: no tracked references found in the dump; cannot compute a path to the GC root. + +TestJMemoryBuddy > testErrorMessages1() PASSED + +TestJMemoryBuddy > testErrorMessages2() STANDARD_OUT + Creating Heapdump at: /Users/floriankirmaier/projects/claude/JMemoryBuddy/build/heapdump_jmemb_2026-06-14_15-47-27.hprof + + JMemoryBuddy — path to GC root for leak: Object @7e0175e48: + GC root [Java frame] Object + + +TestJMemoryBuddy > testErrorMessages2() PASSED + +TestJMemoryBuddy > clearReferenceOnFinalization() STANDARD_OUT + Finalized! + +TestJMemoryBuddy > clearReferenceOnFinalization() PASSED + +TestJMemoryBuddy > negativeTest() STANDARD_OUT + Warning test seems to be unstable. time used: 100% + Creating Heapdump at: /Users/floriankirmaier/projects/claude/JMemoryBuddy/build/heapdump_jmemb_2026-06-14_15-47-28.hprof + + JMemoryBuddy — path to GC root for leak: String @7e016bb00: + GC root [Java frame] String + + The following references should be collected: [someText] + +TestJMemoryBuddy > negativeTest() PASSED + +TestJMemoryBuddy > simpleTestRepeated() PASSED + +TestJMemoryBuddyLive > testMarkKeepsGCBehaviour() PASSED + +Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0. + +You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins. + +For more on this, please refer to https://docs.gradle.org/8.8/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation. + +BUILD SUCCESSFUL in 7s +3 actionable tasks: 1 executed, 2 up-to-date diff --git a/.tmp/jmb-compile.txt b/.tmp/jmb-compile.txt new file mode 100644 index 0000000..772b68d --- /dev/null +++ b/.tmp/jmb-compile.txt @@ -0,0 +1,22 @@ +Downloading https://services.gradle.org/distributions/gradle-8.8-bin.zip +.............10%.............20%.............30%.............40%.............50%.............60%..............70%.............80%.............90%.............100% +WARNING: A restricted method in java.lang.System has been called +WARNING: java.lang.System::load has been called by net.rubygrapefruit.platform.internal.NativeLibraryLoader in an unnamed module (file:/Users/floriankirmaier/.gradle/wrapper/dists/gradle-8.8-bin/dl7vupf4psengwqhwktix4v1/gradle-8.8/lib/native-platform-0.22-milestone-26.jar) +WARNING: Use --enable-native-access=ALL-UNNAMED to avoid a warning for callers in this module +WARNING: Restricted methods will be blocked in a future release unless native access is enabled + +Starting a Gradle Daemon (subsequent builds will be faster) + +FAILURE: Build failed with an exception. + +* What went wrong: +BUG! exception in phase 'semantic analysis' in source unit '_BuildScript_' Unsupported class file major version 69 +> Unsupported class file major version 69 + +* Try: +> Run with --stacktrace option to get the stack trace. +> Run with --info or --debug option to get more log output. +> Run with --scan to get full insights. +> Get more help at https://help.gradle.org. + +BUILD FAILED in 26s diff --git a/.tmp/jmb-multi.txt b/.tmp/jmb-multi.txt new file mode 100644 index 0000000..3415f0d --- /dev/null +++ b/.tmp/jmb-multi.txt @@ -0,0 +1,38 @@ +> Task :compileJava UP-TO-DATE +> Task :processResources NO-SOURCE +> Task :classes UP-TO-DATE + +> Task :compileTestJava +/Users/floriankirmaier/projects/claude/JMemoryBuddy/src/test/java/one/jpro/jmemorybuddy/TestJMemoryBuddy.java:110: warning: [removal] finalize() in Object has been deprecated and marked for removal + protected void finalize() { + ^ +/Users/floriankirmaier/projects/claude/JMemoryBuddy/src/test/java/one/jpro/jmemorybuddy/TestJMemoryBuddy.java:160: warning: [removal] finalize() in Object has been deprecated and marked for removal + protected void finalize() { + ^ +2 warnings + +> Task :processTestResources NO-SOURCE +> Task :testClasses + +> Task :test + +TestJMemoryBuddy > multiHopPath() STANDARD_OUT + Creating Heapdump at: /Users/floriankirmaier/projects/claude/JMemoryBuddy/build/heapdump_jmemb_2026-06-14_15-47-07.hprof + + JMemoryBuddy — path to GC root for leak: Object @58a903060: + GC root [Java frame] TestJMemoryBuddy$Holder + ↓ TestJMemoryBuddy$Holder.field + Object ← leaked + + multiHopPath message: The following references should be collected: [java.lang.Object@3bd323e9] + +TestJMemoryBuddy > multiHopPath() PASSED + +Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0. + +You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins. + +For more on this, please refer to https://docs.gradle.org/8.8/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation. + +BUILD SUCCESSFUL in 2s +3 actionable tasks: 2 executed, 1 up-to-date diff --git a/.tmp/jmb-test.txt b/.tmp/jmb-test.txt new file mode 100644 index 0000000..8ea10dc --- /dev/null +++ b/.tmp/jmb-test.txt @@ -0,0 +1,90 @@ +Starting a Gradle Daemon, 1 incompatible Daemon could not be reused, use --status for details + +> Task :compileJava +/Users/floriankirmaier/projects/claude/JMemoryBuddy/src/main/java/one/jpro/jmemorybuddy/JMemoryBuddy.java:92: warning: [removal] runFinalization() in System has been deprecated and marked for removal + System.runFinalization(); + ^ +/Users/floriankirmaier/projects/claude/JMemoryBuddy/src/main/java/one/jpro/jmemorybuddy/JMemoryBuddy.java:104: warning: [removal] runFinalization() in System has been deprecated and marked for removal + System.runFinalization(); + ^ +/Users/floriankirmaier/projects/claude/JMemoryBuddy/src/main/java/one/jpro/jmemorybuddy/JMemoryBuddy.java:133: warning: [removal] runFinalization() in System has been deprecated and marked for removal + System.runFinalization(); + ^ +3 warnings + +> Task :processResources NO-SOURCE +> Task :classes + +> Task :compileTestJava +/Users/floriankirmaier/projects/claude/JMemoryBuddy/src/test/java/one/jpro/jmemorybuddy/TestJMemoryBuddy.java:110: warning: [removal] finalize() in Object has been deprecated and marked for removal + protected void finalize() { + ^ +/Users/floriankirmaier/projects/claude/JMemoryBuddy/src/test/java/one/jpro/jmemorybuddy/TestJMemoryBuddy.java:160: warning: [removal] finalize() in Object has been deprecated and marked for removal + protected void finalize() { + ^ +2 warnings + +> Task :processTestResources NO-SOURCE +> Task :testClasses + +> Task :test + +TestJMemoryBuddy > testCreateHeapDump() STANDARD_OUT + Creating Heapdump at: /Users/floriankirmaier/projects/claude/JMemoryBuddy/build/heapdump_jmemb_2026-06-14_15-46-20.hprof + +TestJMemoryBuddy > testCreateHeapDump() PASSED + +TestJMemoryBuddy > simpleTest() PASSED + +TestJMemoryBuddy > simpleTest2() PASSED + +TestJMemoryBuddy > simpleTest3() PASSED + +TestJMemoryBuddy > negativeTest2() STANDARD_OUT + Creating Heapdump at: /Users/floriankirmaier/projects/claude/JMemoryBuddy/build/heapdump_jmemb_2026-06-14_15-46-21.hprof + JMemoryBuddy: no tracked references found in the dump; cannot compute a path to the GC root. + The following references should not be collected: [[someText]] + +TestJMemoryBuddy > negativeTest2() PASSED + +TestJMemoryBuddy > testErrorMessages1() STANDARD_OUT + Creating Heapdump at: /Users/floriankirmaier/projects/claude/JMemoryBuddy/build/heapdump_jmemb_2026-06-14_15-46-22.hprof + JMemoryBuddy: no tracked references found in the dump; cannot compute a path to the GC root. + +TestJMemoryBuddy > testErrorMessages1() PASSED + +TestJMemoryBuddy > testErrorMessages2() STANDARD_OUT + Creating Heapdump at: /Users/floriankirmaier/projects/claude/JMemoryBuddy/build/heapdump_jmemb_2026-06-14_15-46-23.hprof + + JMemoryBuddy — path to GC root for leak: Object @58aa4a348: + GC root [Java frame] Object + + +TestJMemoryBuddy > testErrorMessages2() PASSED + +TestJMemoryBuddy > clearReferenceOnFinalization() STANDARD_OUT + Finalized! + +TestJMemoryBuddy > clearReferenceOnFinalization() PASSED + +TestJMemoryBuddy > negativeTest() STANDARD_OUT + Warning test seems to be unstable. time used: 100% + Creating Heapdump at: /Users/floriankirmaier/projects/claude/JMemoryBuddy/build/heapdump_jmemb_2026-06-14_15-46-24.hprof + + JMemoryBuddy — path to GC root for leak: String @58ab06948: + GC root [Java frame] String + + The following references should be collected: [someText] + +TestJMemoryBuddy > negativeTest() PASSED + +TestJMemoryBuddy > simpleTestRepeated() PASSED + +Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0. + +You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins. + +For more on this, please refer to https://docs.gradle.org/8.8/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation. + +BUILD SUCCESSFUL in 13s +3 actionable tasks: 3 executed diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c57ab2..4da61c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ ### 0.5.7 (TBD) +* On a failed leak check, JMemoryBuddy now reads back the heap dump it creates and prints the strong-reference path from a GC root to each not-collected object — no need to open VisualVM/MAT for the common case. Dependency-free; disable with `-Djmemorybuddy.printPath=false`. ### 0.5.6 (October 29, 2024) diff --git a/README.md b/README.md index 7dbd395..d82a9e2 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,17 @@ You can also use the method `assertCollectable` and `assertNotCollectable` to ch #### Analyzing the heap dump: -JMemoryBuddy makes it easy to analyze the heap dump because all problematic instances are wrapped inside a class with the name `AssertCollectable`. Just search your heap dump with your prefered tool for this class name: +On a failed leak check JMemoryBuddy reads back the heap dump and prints the strong-reference path from a GC root to each not-collected object directly in the test output — usually enough to find the cause without opening any tool: + +``` +JMemoryBuddy — path to GC root for leak: PageDoc @58a903060: + GC root [Java frame] DataRepository + ↓ DataRepository.listeners + ... + PageDoc ← leaked +``` + +Disable with `-Djmemorybuddy.printPath=false`. For a deeper look, open the dump in your preferred tool — all watched instances are referenced by a `TrackedWeakReference`, so you can search for that class name:  @@ -74,6 +84,8 @@ You can configure VisualVM with SystemProperties: | Tables | Effect | Default | | ------------- |:-------------:| -----:| | -Djmemorybuddy.createHeapDump | Should a heap dump created on failure? | true | +| -Djmemorybuddy.printPath | Print the path from a GC root to each not-collected object on failure. | true | +| -Djmemorybuddy.maxObjects | Skip the path analysis when the dump has more objects than this (avoids heavy in-process analysis). | 8000000 | | -Djmemorybuddy.output | The folder where the heap dump gets saved. | if target exists, then "target" otherwise "build" | The following values usually shouldn't be changed but might be useful to make tests more stable or reduce the time required. diff --git a/build/classes/java/main/module-info.class b/build/classes/java/main/module-info.class new file mode 100644 index 0000000..18d89e1 Binary files /dev/null and b/build/classes/java/main/module-info.class differ diff --git a/build/classes/java/main/one/jpro/jmemorybuddy/CleanupDetector$WeakReferenceWithRunnable.class b/build/classes/java/main/one/jpro/jmemorybuddy/CleanupDetector$WeakReferenceWithRunnable.class new file mode 100644 index 0000000..f0b5e96 Binary files /dev/null and b/build/classes/java/main/one/jpro/jmemorybuddy/CleanupDetector$WeakReferenceWithRunnable.class differ diff --git a/build/classes/java/main/one/jpro/jmemorybuddy/CleanupDetector.class b/build/classes/java/main/one/jpro/jmemorybuddy/CleanupDetector.class new file mode 100644 index 0000000..1ad50e3 Binary files /dev/null and b/build/classes/java/main/one/jpro/jmemorybuddy/CleanupDetector.class differ diff --git a/build/classes/java/main/one/jpro/jmemorybuddy/HeapPath$ClassInfo.class b/build/classes/java/main/one/jpro/jmemorybuddy/HeapPath$ClassInfo.class new file mode 100644 index 0000000..cffb3b6 Binary files /dev/null and b/build/classes/java/main/one/jpro/jmemorybuddy/HeapPath$ClassInfo.class differ diff --git a/build/classes/java/main/one/jpro/jmemorybuddy/HeapPath$Counter.class b/build/classes/java/main/one/jpro/jmemorybuddy/HeapPath$Counter.class new file mode 100644 index 0000000..3c3c522 Binary files /dev/null and b/build/classes/java/main/one/jpro/jmemorybuddy/HeapPath$Counter.class differ diff --git a/build/classes/java/main/one/jpro/jmemorybuddy/HeapPath.class b/build/classes/java/main/one/jpro/jmemorybuddy/HeapPath.class new file mode 100644 index 0000000..fb8eec0 Binary files /dev/null and b/build/classes/java/main/one/jpro/jmemorybuddy/HeapPath.class differ diff --git a/build/classes/java/main/one/jpro/jmemorybuddy/JMemoryBuddy$1.class b/build/classes/java/main/one/jpro/jmemorybuddy/JMemoryBuddy$1.class new file mode 100644 index 0000000..6738fb1 Binary files /dev/null and b/build/classes/java/main/one/jpro/jmemorybuddy/JMemoryBuddy$1.class differ diff --git a/build/classes/java/main/one/jpro/jmemorybuddy/JMemoryBuddy$AssertCollectable.class b/build/classes/java/main/one/jpro/jmemorybuddy/JMemoryBuddy$AssertCollectable.class new file mode 100644 index 0000000..4fe498d Binary files /dev/null and b/build/classes/java/main/one/jpro/jmemorybuddy/JMemoryBuddy$AssertCollectable.class differ diff --git a/build/classes/java/main/one/jpro/jmemorybuddy/JMemoryBuddy$AssertNotCollectable.class b/build/classes/java/main/one/jpro/jmemorybuddy/JMemoryBuddy$AssertNotCollectable.class new file mode 100644 index 0000000..03a1f50 Binary files /dev/null and b/build/classes/java/main/one/jpro/jmemorybuddy/JMemoryBuddy$AssertNotCollectable.class differ diff --git a/build/classes/java/main/one/jpro/jmemorybuddy/JMemoryBuddy$MemoryTestAPI.class b/build/classes/java/main/one/jpro/jmemorybuddy/JMemoryBuddy$MemoryTestAPI.class new file mode 100644 index 0000000..cb10481 Binary files /dev/null and b/build/classes/java/main/one/jpro/jmemorybuddy/JMemoryBuddy$MemoryTestAPI.class differ diff --git a/build/classes/java/main/one/jpro/jmemorybuddy/JMemoryBuddy$SetAsReferenced.class b/build/classes/java/main/one/jpro/jmemorybuddy/JMemoryBuddy$SetAsReferenced.class new file mode 100644 index 0000000..a95b47d Binary files /dev/null and b/build/classes/java/main/one/jpro/jmemorybuddy/JMemoryBuddy$SetAsReferenced.class differ diff --git a/build/classes/java/main/one/jpro/jmemorybuddy/JMemoryBuddy.class b/build/classes/java/main/one/jpro/jmemorybuddy/JMemoryBuddy.class new file mode 100644 index 0000000..bb103e2 Binary files /dev/null and b/build/classes/java/main/one/jpro/jmemorybuddy/JMemoryBuddy.class differ diff --git a/build/classes/java/main/one/jpro/jmemorybuddy/JMemoryBuddyLive$AssertCollectableLive.class b/build/classes/java/main/one/jpro/jmemorybuddy/JMemoryBuddyLive$AssertCollectableLive.class new file mode 100644 index 0000000..fd49238 Binary files /dev/null and b/build/classes/java/main/one/jpro/jmemorybuddy/JMemoryBuddyLive$AssertCollectableLive.class differ diff --git a/build/classes/java/main/one/jpro/jmemorybuddy/JMemoryBuddyLive$CollectableEntry.class b/build/classes/java/main/one/jpro/jmemorybuddy/JMemoryBuddyLive$CollectableEntry.class new file mode 100644 index 0000000..112f9f4 Binary files /dev/null and b/build/classes/java/main/one/jpro/jmemorybuddy/JMemoryBuddyLive$CollectableEntry.class differ diff --git a/build/classes/java/main/one/jpro/jmemorybuddy/JMemoryBuddyLive$Report.class b/build/classes/java/main/one/jpro/jmemorybuddy/JMemoryBuddyLive$Report.class new file mode 100644 index 0000000..24fbc7b Binary files /dev/null and b/build/classes/java/main/one/jpro/jmemorybuddy/JMemoryBuddyLive$Report.class differ diff --git a/build/classes/java/main/one/jpro/jmemorybuddy/JMemoryBuddyLive.class b/build/classes/java/main/one/jpro/jmemorybuddy/JMemoryBuddyLive.class new file mode 100644 index 0000000..c8b1863 Binary files /dev/null and b/build/classes/java/main/one/jpro/jmemorybuddy/JMemoryBuddyLive.class differ diff --git a/build/classes/java/main/one/jpro/jmemorybuddy/TrackedWeakReference.class b/build/classes/java/main/one/jpro/jmemorybuddy/TrackedWeakReference.class new file mode 100644 index 0000000..8505e8c Binary files /dev/null and b/build/classes/java/main/one/jpro/jmemorybuddy/TrackedWeakReference.class differ diff --git a/build/classes/java/test/one/jpro/jmemorybuddy/TestCleanupDetector.class b/build/classes/java/test/one/jpro/jmemorybuddy/TestCleanupDetector.class new file mode 100644 index 0000000..78a8af4 Binary files /dev/null and b/build/classes/java/test/one/jpro/jmemorybuddy/TestCleanupDetector.class differ diff --git a/build/classes/java/test/one/jpro/jmemorybuddy/TestJMemoryBuddy$1.class b/build/classes/java/test/one/jpro/jmemorybuddy/TestJMemoryBuddy$1.class new file mode 100644 index 0000000..102bc59 Binary files /dev/null and b/build/classes/java/test/one/jpro/jmemorybuddy/TestJMemoryBuddy$1.class differ diff --git a/build/classes/java/test/one/jpro/jmemorybuddy/TestJMemoryBuddy$2.class b/build/classes/java/test/one/jpro/jmemorybuddy/TestJMemoryBuddy$2.class new file mode 100644 index 0000000..3982e45 Binary files /dev/null and b/build/classes/java/test/one/jpro/jmemorybuddy/TestJMemoryBuddy$2.class differ diff --git a/build/classes/java/test/one/jpro/jmemorybuddy/TestJMemoryBuddy$A.class b/build/classes/java/test/one/jpro/jmemorybuddy/TestJMemoryBuddy$A.class new file mode 100644 index 0000000..a4f57b5 Binary files /dev/null and b/build/classes/java/test/one/jpro/jmemorybuddy/TestJMemoryBuddy$A.class differ diff --git a/build/classes/java/test/one/jpro/jmemorybuddy/TestJMemoryBuddy$Holder.class b/build/classes/java/test/one/jpro/jmemorybuddy/TestJMemoryBuddy$Holder.class new file mode 100644 index 0000000..57612ba Binary files /dev/null and b/build/classes/java/test/one/jpro/jmemorybuddy/TestJMemoryBuddy$Holder.class differ diff --git a/build/classes/java/test/one/jpro/jmemorybuddy/TestJMemoryBuddy.class b/build/classes/java/test/one/jpro/jmemorybuddy/TestJMemoryBuddy.class new file mode 100644 index 0000000..df9766d Binary files /dev/null and b/build/classes/java/test/one/jpro/jmemorybuddy/TestJMemoryBuddy.class differ diff --git a/build/classes/java/test/one/jpro/jmemorybuddy/TestJMemoryBuddyLive.class b/build/classes/java/test/one/jpro/jmemorybuddy/TestJMemoryBuddyLive.class new file mode 100644 index 0000000..f058274 Binary files /dev/null and b/build/classes/java/test/one/jpro/jmemorybuddy/TestJMemoryBuddyLive.class differ diff --git a/build/heapdump_jmemb_2026-06-14_15-46-20.hprof b/build/heapdump_jmemb_2026-06-14_15-46-20.hprof new file mode 100644 index 0000000..815ffb8 Binary files /dev/null and b/build/heapdump_jmemb_2026-06-14_15-46-20.hprof differ diff --git a/build/heapdump_jmemb_2026-06-14_15-46-21.hprof b/build/heapdump_jmemb_2026-06-14_15-46-21.hprof new file mode 100644 index 0000000..ee1b1e4 Binary files /dev/null and b/build/heapdump_jmemb_2026-06-14_15-46-21.hprof differ diff --git a/build/heapdump_jmemb_2026-06-14_15-46-22.hprof b/build/heapdump_jmemb_2026-06-14_15-46-22.hprof new file mode 100644 index 0000000..d05a5f5 Binary files /dev/null and b/build/heapdump_jmemb_2026-06-14_15-46-22.hprof differ diff --git a/build/heapdump_jmemb_2026-06-14_15-46-23.hprof b/build/heapdump_jmemb_2026-06-14_15-46-23.hprof new file mode 100644 index 0000000..6917190 Binary files /dev/null and b/build/heapdump_jmemb_2026-06-14_15-46-23.hprof differ diff --git a/build/heapdump_jmemb_2026-06-14_15-46-24.hprof b/build/heapdump_jmemb_2026-06-14_15-46-24.hprof new file mode 100644 index 0000000..69f5286 Binary files /dev/null and b/build/heapdump_jmemb_2026-06-14_15-46-24.hprof differ diff --git a/build/heapdump_jmemb_2026-06-14_15-47-07.hprof b/build/heapdump_jmemb_2026-06-14_15-47-07.hprof new file mode 100644 index 0000000..dbf9965 Binary files /dev/null and b/build/heapdump_jmemb_2026-06-14_15-47-07.hprof differ diff --git a/build/heapdump_jmemb_2026-06-14_15-47-23.hprof b/build/heapdump_jmemb_2026-06-14_15-47-23.hprof new file mode 100644 index 0000000..0d2c1b9 Binary files /dev/null and b/build/heapdump_jmemb_2026-06-14_15-47-23.hprof differ diff --git a/build/heapdump_jmemb_2026-06-14_15-47-25.hprof b/build/heapdump_jmemb_2026-06-14_15-47-25.hprof new file mode 100644 index 0000000..bec9746 Binary files /dev/null and b/build/heapdump_jmemb_2026-06-14_15-47-25.hprof differ diff --git a/build/heapdump_jmemb_2026-06-14_15-47-26.hprof b/build/heapdump_jmemb_2026-06-14_15-47-26.hprof new file mode 100644 index 0000000..2c0271a Binary files /dev/null and b/build/heapdump_jmemb_2026-06-14_15-47-26.hprof differ diff --git a/build/heapdump_jmemb_2026-06-14_15-47-27.hprof b/build/heapdump_jmemb_2026-06-14_15-47-27.hprof new file mode 100644 index 0000000..8fc95a4 Binary files /dev/null and b/build/heapdump_jmemb_2026-06-14_15-47-27.hprof differ diff --git a/build/heapdump_jmemb_2026-06-14_15-47-28.hprof b/build/heapdump_jmemb_2026-06-14_15-47-28.hprof new file mode 100644 index 0000000..b3916fa Binary files /dev/null and b/build/heapdump_jmemb_2026-06-14_15-47-28.hprof differ diff --git a/build/reports/tests/test/classes/one.jpro.jmemorybuddy.TestCleanupDetector.html b/build/reports/tests/test/classes/one.jpro.jmemorybuddy.TestCleanupDetector.html new file mode 100644 index 0000000..9d1bb3d --- /dev/null +++ b/build/reports/tests/test/classes/one.jpro.jmemorybuddy.TestCleanupDetector.html @@ -0,0 +1,101 @@ + + +
+ + +|
+
+
+
|
+
+
+
+100%
+successful + |
+
| Test | +Duration | +Result | +
|---|---|---|
| isPhantomRefCollectable() | +1.121s | +passed | +
| isRunnableCalled() | +0.017s | +passed | +
|
+
+
+
|
+
+
+
+100%
+successful + |
+
| Test | +Duration | +Result | +
|---|---|---|
| clearReferenceOnFinalization() | +0.118s | +passed | +
| multiHopPath() | +1.302s | +passed | +
| negativeTest() | +1.273s | +passed | +
| negativeTest2() | +0.017s | +passed | +
| simpleTest() | +0.006s | +passed | +
| simpleTest2() | +0.016s | +passed | +
| simpleTest3() | +0.764s | +passed | +
| simpleTestRepeated() | +0.524s | +passed | +
| testCreateHeapDump() | +0.087s | +passed | +
| testErrorMessages1() | +0.164s | +passed | +
| testErrorMessages2() | +1.284s | +passed | +
Creating Heapdump at: /Users/floriankirmaier/projects/claude/JMemoryBuddy/build/heapdump_jmemb_2026-06-14_15-47-23.hprof +Creating Heapdump at: /Users/floriankirmaier/projects/claude/JMemoryBuddy/build/heapdump_jmemb_2026-06-14_15-47-25.hprof + +JMemoryBuddy — path to GC root for leak: Object @7e016b900: + GC root [Java frame] TestJMemoryBuddy$Holder + ↓ TestJMemoryBuddy$Holder.field + Object ← leaked + +multiHopPath message: The following references should be collected: [java.lang.Object@67d18ed7] +Creating Heapdump at: /Users/floriankirmaier/projects/claude/JMemoryBuddy/build/heapdump_jmemb_2026-06-14_15-47-25.hprof +The following references should not be collected: [[someText]] +Creating Heapdump at: /Users/floriankirmaier/projects/claude/JMemoryBuddy/build/heapdump_jmemb_2026-06-14_15-47-26.hprof +JMemoryBuddy: no tracked references found in the dump; cannot compute a path to the GC root. +Creating Heapdump at: /Users/floriankirmaier/projects/claude/JMemoryBuddy/build/heapdump_jmemb_2026-06-14_15-47-27.hprof + +JMemoryBuddy — path to GC root for leak: Object @7e0175e48: + GC root [Java frame] Object + +Finalized! +Warning test seems to be unstable. time used: 100% +Creating Heapdump at: /Users/floriankirmaier/projects/claude/JMemoryBuddy/build/heapdump_jmemb_2026-06-14_15-47-28.hprof + +JMemoryBuddy — path to GC root for leak: String @7e016bb00: + GC root [Java frame] String + +The following references should be collected: [someText] ++ +
java.io.IOException: File exists + at jdk.management/com.sun.management.internal.HotSpotDiagnostic.dumpHeap0(Native Method) + at jdk.management/com.sun.management.internal.HotSpotDiagnostic.dumpHeap(HotSpotDiagnostic.java:70) + at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) + at java.base/java.lang.reflect.Method.invoke(Method.java:580) + at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:64) + at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) + at java.base/java.lang.reflect.Method.invoke(Method.java:580) + at java.base/sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:97) + at java.management/com.sun.jmx.mbeanserver.ConvertingMethod.invokeWithOpenReturn(ConvertingMethod.java:193) + at java.management/com.sun.jmx.mbeanserver.ConvertingMethod.invokeWithOpenReturn(ConvertingMethod.java:175) + at java.management/com.sun.jmx.mbeanserver.MXBeanIntrospector.invokeM2(MXBeanIntrospector.java:115) + at java.management/com.sun.jmx.mbeanserver.MXBeanIntrospector.invokeM2(MXBeanIntrospector.java:52) + at java.management/com.sun.jmx.mbeanserver.MBeanIntrospector.invokeM(MBeanIntrospector.java:236) + at java.management/com.sun.jmx.mbeanserver.PerInterface.invoke(PerInterface.java:138) + at java.management/com.sun.jmx.mbeanserver.MBeanSupport.invoke(MBeanSupport.java:252) + at java.management/javax.management.StandardMBean.invoke(StandardMBean.java:405) + at java.management/com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:803) + at java.management/com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:802) + at java.management/com.sun.jmx.mbeanserver.MXBeanProxy$InvokeHandler.invoke(MXBeanProxy.java:150) + at java.management/com.sun.jmx.mbeanserver.MXBeanProxy.invoke(MXBeanProxy.java:167) + at java.management/javax.management.MBeanServerInvocationHandler.invoke(MBeanServerInvocationHandler.java:258) + at jdk.proxy2/jdk.proxy2.$Proxy12.dumpHeap(Unknown Source) + at one.jpro.jmemorybuddy.JMemoryBuddy.createHeapDump(JMemoryBuddy.java:212) + at one.jpro.jmemorybuddy.JMemoryBuddy.memoryTest(JMemoryBuddy.java:193) + at one.jpro.jmemorybuddy.TestJMemoryBuddy.negativeTest2(TestJMemoryBuddy.java:90) + at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) + at java.base/java.lang.reflect.Method.invoke(Method.java:580) + at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:767) + at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60) + at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131) + at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156) + at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147) + at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86) + at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103) + at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93) + at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106) + at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64) + at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45) + at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37) + at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92) + at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86) + at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$8(TestMethodTestDescriptor.java:217) + at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:213) + at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:138) + at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:156) + at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:146) + at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:144) + at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:143) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:100) + at java.base/java.util.ArrayList.forEach(ArrayList.java:1596) + at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:160) + at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:146) + at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:144) + at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:143) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:100) + at java.base/java.util.ArrayList.forEach(ArrayList.java:1596) + at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:160) + at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:146) + at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:144) + at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:143) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:100) + at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35) + at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) + at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54) + at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107) + at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88) + at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54) + at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67) + at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52) + at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114) + at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86) + at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86) + at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:119) + at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:94) + at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:89) + at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62) + at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) + at java.base/java.lang.reflect.Method.invoke(Method.java:580) + at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36) + at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) + at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33) + at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94) + at jdk.proxy1/jdk.proxy1.$Proxy2.stop(Unknown Source) + at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193) + at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129) + at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100) + at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60) + at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56) + at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:119) + at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:66) + at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69) + at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74) ++ +
|
+
+
+
|
+
+
+
+100%
+successful + |
+
| Test | +Duration | +Result | +
|---|---|---|
| testMarkKeepsGCBehaviour() | +0.060s | +passed | +
|
+
+
+
|
+
+
+
+100%
+successful + |
+
| Package | +Tests | +Failures | +Ignored | +Duration | +Success rate | +
|---|---|---|---|---|---|
| +one.jpro.jmemorybuddy + | +14 | +0 | +0 | +6.753s | +100% | +
| Class | +Tests | +Failures | +Ignored | +Duration | +Success rate | +
|---|---|---|---|---|---|
| +one.jpro.jmemorybuddy.TestCleanupDetector + | +2 | +0 | +0 | +1.138s | +100% | +
| +one.jpro.jmemorybuddy.TestJMemoryBuddy + | +11 | +0 | +0 | +5.555s | +100% | +
| +one.jpro.jmemorybuddy.TestJMemoryBuddyLive + | +1 | +0 | +0 | +0.060s | +100% | +
|
+
+
+
|
+
+
+
+100%
+successful + |
+
| Class | +Tests | +Failures | +Ignored | +Duration | +Success rate | +
|---|---|---|---|---|---|
| +TestCleanupDetector + | +2 | +0 | +0 | +1.138s | +100% | +
| +TestJMemoryBuddy + | +11 | +0 | +0 | +5.555s | +100% | +
| +TestJMemoryBuddyLive + | +1 | +0 | +0 | +0.060s | +100% | +
Best-effort: on any parse problem or when the heap exceeds {@code maxObjects} the
+ * analysis is skipped silently — the heap dump itself is always still written.
+ */
+final class HeapPath {
+
+ // HPROF top-level record tags
+ private static final int TAG_STRING = 0x01;
+ private static final int TAG_LOAD_CLASS = 0x02;
+ private static final int TAG_HEAP_DUMP = 0x0C;
+ private static final int TAG_HEAP_DUMP_SEGMENT = 0x1C;
+
+ // HPROF heap-dump sub-record tags
+ private static final int ROOT_JNI_GLOBAL = 0x01;
+ private static final int ROOT_JNI_LOCAL = 0x02;
+ private static final int ROOT_JAVA_FRAME = 0x03;
+ private static final int ROOT_NATIVE_STACK = 0x04;
+ private static final int ROOT_STICKY_CLASS = 0x05;
+ private static final int ROOT_THREAD_BLOCK = 0x06;
+ private static final int ROOT_MONITOR_USED = 0x07;
+ private static final int ROOT_THREAD_OBJECT = 0x08;
+ private static final int ROOT_UNKNOWN = 0xFF;
+ private static final int CLASS_DUMP = 0x20;
+ private static final int INSTANCE_DUMP = 0x21;
+ private static final int OBJECT_ARRAY_DUMP = 0x22;
+ private static final int PRIMITIVE_ARRAY_DUMP = 0x23;
+
+ private static final String TRACKED_REF = TrackedWeakReference.class.getName();
+
+ private final String path;
+ private final int maxObjects;
+ private int idSize;
+
+ private final Map