JDK-8151158 : [TESTBUG] java/util/concurrent/forkjoin/FJExceptionTableLeak.java fails due to out of memory
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util.concurrent
  • Affected Version: 9
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2016-03-03
  • Updated: 2017-03-21
  • Resolved: 2016-08-15
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9 b132Fixed
Related Reports
Relates :  
Relates :  
Description
The test java/util/concurrent/forkjoin/FJExceptionTableLeak.java fails in the compiler nightly testing of 2016-03-02 due to out of memory. The platform is "Sun Sparcv9 3600 MHz, 8 cores, 16G, Solaris / Solaris 11, sun4v".

The test is run with -Xmx8m. That might give too little memory to run the test.
Comments
Ah I see. Okay that design is going to have an issue with a test that takes that design to its limits. Adding some judicious System.gc() calls in the test loop may help.
19-07-2016

The data structure really is static, and we *do* have a race against GC reference processing. The test does nothing but execute failing fork join tasks. This is a typical example of trouble when you rely on the GC for cleanup actions. /** * Hash table of exceptions thrown by tasks, to enable reporting * by callers. Because exceptions are rare, we don't directly keep * them with task objects, but instead use a weak ref table. Note * that cancellation exceptions don't appear in the table, but are * instead recorded as status values. * * The exception table has a fixed capacity. */ private static final ExceptionNode[] exceptionTable = new ExceptionNode[32]; /** Lock protecting access to exceptionTable. */ private static final ReentrantLock exceptionTableLock = new ReentrantLock(); /** Reference queue of stale exceptionally completed tasks. */ private static final ReferenceQueue<ForkJoinTask<?>> exceptionTableRefQueue = new ReferenceQueue<ForkJoinTask<?>>();
19-07-2016

Lets assume all we have is strong references, do we expect that the number of tasks executed by the test would be sufficient to exhaust the 8MB heap? If yes then yes we are racing with GC. If the FJP threads are keeping references to things across task invocations that would be wrong. Otherwise, yes it may be a race against GC reference processing.
19-07-2016

Hmmmm.... looking again ... The exception table is a static data structure that relies on weak references and a reference queue to release memory. Which explains why the UEH itself gets an OOME because popping all the stack frames causes no gc root to be freed. Maybe this is indeed a problem with the forkjoin code itself, or the test is too sensitively dependent on the speed of the GC finding weak references. Time for me to stop blaming hotspot for this particular bug ?
19-07-2016

If we are running out of Java heap then that is hardly a VM footprint issue. But I'm not clear on exactly what kind of OOME we are seeing here Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "main" This is printed by the VM when handling the uncaughtException itself raises an exception - in this case OOME. So we don't know what the original exception was (it may also be OOME). This needs more investigation than just tweaking heap sizes. We need to see a failure with VM exception logging enabled.
18-07-2016

After JDK-8144990, still observed this test failed intermittently due to: Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "MainThread" Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "main"
18-07-2016

It's disturbing to me that small Java programs require increasingly greater -Xmx values to be able to run at all. I used to be able to run small trivial tests with -Xmx2200k for years, but now -Xmx8m is not enough? I wish VM engineers paid as much attention to footprint as raw cpu performance. It is likely that small memory java.util.concurrent tests will use a different approach to detect leaks in the future.
04-07-2016