JDK-8154063 : Event Handles Leak by java.lang.Thread
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 8,9
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_7
  • CPU: x86_64
  • Submitted: 2016-04-06
  • Updated: 2016-06-07
  • Resolved: 2016-06-06
Description
FULL PRODUCT VERSION :
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
This is applicable for all windows platform JRE. I have tested this on windows 7 64 bit 
Ver Output: W7-O-140123-072

A DESCRIPTION OF THE PROBLEM :
When you create a thread in java and use the Thread.sleep command, it creates a internal system event on windows but does not close the handle for the same.  To capture the handle output I have used the "handle" utility provided by Microsoft which shows that after all the 3000 threads are there are 15000 odd event handles still open. 

Download the handle utility from the following location 
https://technet.microsoft.com/en-us/sysinternals/handle.aspx

If you update the run method with just a sysout instead of the sleep like below

 @Override
    public void run()
    {
        System.out.println(Thread.currentThread().getName() + " Done!");
     }

it still leaks 1700 event handles.

These handles are not cleared even after garbage collection. Is this a bug or expected behavior ? Can these leaks cause the JVM to crash and go out of memory


REGRESSION.  Last worked in version 8u72

ADDITIONAL REGRESSION INFORMATION: 
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Download the attached java file
2. Download handle utility from (https://technet.microsoft.com/en-us/sysinternals/handle.aspx)
3. Compile the attached java file : javac TestThread.java
4. Run using java TestThread
5. Capture the process id from task manager (Say PID:1000)
6. Run the following command: handle.exe -s -p <<PID>>
7. The programs stops for 15 seconds to capture the handle output
8. Run the same command on step 6 after the program print GC Done. Current Active Thread Count 1
9. The event count does not match
7. Kill the program by using ctrl+C on the command prompt


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The handle if any are open should be closed after the thread has exited. 
ACTUAL -
See a leak of 15000 odd thread event handles instead of none

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class TestThread
{

    public static void main(String[] args)
    {

        try
        {
            Thread.sleep(15000);
        }
        catch (InterruptedException e)
        {
        }

        for (int i = 0; i < 3000; i++)
        {
            MyThread thd = new MyThread();
            thd.setName("DummyThd-"+Integer.toString(i));
            thd.start();
        }

        System.out.println("Sleeping for 15 secs");
        try
        {
            Thread.sleep(15000);
        }
        catch (InterruptedException e)
        {
        }

        System.gc();
        System.out.println("GC Done");

        System.out.println("Current Active Thread Count " + Thread.activeCount());

        Thread thd = new JustKeepRunning();
        thd.start();
        try
        {
            thd.join();
        }
        catch (InterruptedException e)
        {
        }

    }
}

class MyThread extends Thread
{

    @Override
    public void run()
    {
        try
        {
            Thread.sleep(5000);
            System.out.println(Thread.currentThread().getName() + " Done!");
        }
        catch (InterruptedException e)
        {
            // do nothing
        }
    }
}

class JustKeepRunning extends Thread
{

    @Override
    public void run()
    {
        while (true)
        {
            try
            {
                Thread.sleep(500000);
                System.out.println(Thread.currentThread().getName() + " Done!");
            }
            catch (InterruptedException e)
            {
                // do nothing
            }
        }
    }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
None found.


Comments
Closing as duplicate of JDK-8145999.
06-06-2016

Related bug?
03-06-2016

I assume this should start out in hotspot/runtime.
03-06-2016

Correction. The VM maintains a pool of PlatformEvent objects (which maps to Events on Windows). This pool will grow to the maximum needed by the maximum number of concurrent threads that exist in the VM at one time. We tend to run out of memory to create threads well before we run out of Handles. So during the first sleep only the main thread and a few VM threads exist and the overall handle count is low. We then start 3000 threads, each of which uses at least 5 Handles (and based on the reported output I'm assuming there is a 6th hiding in the implementation somewhere). Then depending on machine size and scheduling there will be some variance in the number of concurrent threads, but assume all 3000 and it is easy to see where the peak numbers come from. Note not all handles are associated with Events so they will be reclaimed when the thread dies - hence the drop to 15000 after all the 3000 threads have terminated.
03-06-2016

Test Result: ########## OS: Windows 7 64-bit JDK: 8uXX, 9ea ================================================= D:\MyApps\Submitter_Apps>jps 10112 TestThread 4288 16964 Jps 1992 20092 TestThread D:\MyApps\Submitter_Apps>Handle.exe -s -p 20092 Handle v4.0 Copyright (C) 1997-2014 Mark Russinovich Sysinternals - www.sysinternals.com Handle type summary: ALPC Port : 2 Desktop : 1 Directory : 2 EtwRegistration : 13 Event : 98 ==========================> Before printing ["Sleeping for 15 secs"] File : 6 Key : 6 Mutant : 3 Section : 2 Semaphore : 2 Thread : 17 WindowStation : 2 Total handles: 154 D:\MyApps\Submitter_Apps>Handle.exe -s -p 20092 Handle v4.0 Copyright (C) 1997-2014 Mark Russinovich Sysinternals - www.sysinternals.com Handle type summary: ALPC Port : 2 Desktop : 1 Directory : 2 EtwRegistration : 13 Event : 18098 ==========================> After printing ["Sleeping for 15 secs"] File : 6 Key : 6 Mutant : 3 Section : 2 Semaphore : 2 Thread : 3017 WindowStation : 2 Total handles: 21154 D:\MyApps\Submitter_Apps>Handle.exe -s -p 20092 Handle v4.0 Copyright (C) 1997-2014 Mark Russinovich Sysinternals - www.sysinternals.com Handle type summary: ALPC Port : 2 Desktop : 1 Directory : 2 EtwRegistration : 13 Event : 15098 ======================> Before printing "GC Done" File : 6 Key : 6 Mutant : 3 Section : 2 Semaphore : 2 Thread : 17 WindowStation : 2 Total handles: 15154 D:\MyApps\Submitter_Apps>Handle.exe -s -p 20092 Handle v4.0 Copyright (C) 1997-2014 Mark Russinovich Sysinternals - www.sysinternals.com Handle type summary: ALPC Port : 2 Desktop : 1 Directory : 2 EtwRegistration : 13 Event : 15099 ======================> After printing "GC Done" File : 6 Key : 6 Mutant : 3 Section : 2 Semaphore : 2 Thread : 18 WindowStation : 2 Total handles: 15156 D:\MyApps\Submitter_Apps>
12-04-2016