United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6559427 Attach mechanism leaks tool-side handle per command
JDK-6559427 : Attach mechanism leaks tool-side handle per command

Details
Type:
Bug
Submit Date:
2007-05-18
Status:
Closed
Updated Date:
2011-03-08
Project Name:
JDK
Resolved Date:
2011-03-08
Component:
core-svc
OS:
solaris_2.5.1
Sub-Component:
tools
CPU:
sparc
Priority:
P2
Resolution:
Fixed
Affected Versions:
6u1
Fixed Versions:

Related Reports
Backport:

Sub Tasks

Description
Calling the native method sun.tools.attach.WindowsVirtualMachine.enqueue() repeatedly will cause a leak of Windows handles returned by the call to CreateRemoteThread(). This can be shown by the following simple Java program.

This becomes a real problem when the attach framework is used to repeatedly try to attach to other JVMs in order to automatically discover them and their parameters, which is exactly what JRockit Mission Control 2.0 does since JRockit R27.1 and forward.

If the number of handles allocated by the Java process becomes too large, this will cause the Windows system to hang and become unresponsive.

Reproducer code:

package sun.tools.attach;

import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import sun.tools.attach.HotSpotVirtualMachine;
import sun.tools.attach.HotSpotVirtualMachineAccess;
import com.sun.tools.attach.AgentLoadException;
import com.sun.tools.attach.AttachNotSupportedException;
import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.VirtualMachineDescriptor;

public class AttachTester
{

    public static void main(String[] args) throws AttachNotSupportedException, Exception, AgentLoadException
    {
	String pid = args[0];
	int times = Integer.parseInt(args[1]);
	int sleepmillis = Integer.parseInt(args[2]);
	boolean executeCommand = Boolean.parseBoolean(args[3]);

	for (int i = 0; i < times; i++)
	{
	    Iterator it = VirtualMachine.list().iterator();
	    while (it.hasNext())
	    {
		VirtualMachineDescriptor descriptor = (VirtualMachineDescriptor) it.next();
		if (pid.equals(descriptor.id()))
		{
		    System.out.println("Iteration " + i);
		    System.out.println("Attaching to pid " +pid);
		    VirtualMachine machine = VirtualMachine.attach(descriptor);
		    HotSpotVirtualMachine hvm = (HotSpotVirtualMachine) machine;

		    if (executeCommand)
		    {
			InputStream in = HotSpotVirtualMachineAccess.execute(hvm, "printflag", "hello" );
			byte b[] = new byte[256];
			int n;
			StringBuffer buf = new StringBuffer();
			do
			{
			    n = in.read(b);
			    if (n > 0)
			    {
				String s = new String(b, 0, n, "UTF-8"); //$NON-NLS-1$
				buf.append(s);
			    }
			}
			while (n > 0);

			try
			{
			    in.close();
			}
			catch (IOException ex)
			{
			    System.out.println("Could not close stream.");
			}
			System.out.println(i + " " + buf.toString());
		    }
		    System.out.println("Detaching from pid " +pid);
		    machine.detach();
		}
	    }
	    System.out.println("Sleeping "+ sleepmillis + " ms");
	    System.out.println();
	    System.out.println();
		
	    Thread.sleep(sleepmillis);
	}
    }
}

/**
 * This class only exists because HotSpotVirtualMachine.execute() is made
 * package-private by Sun.
 */

public class HotSpotVirtualMachineAccess
{
   public static InputStream execute(HotSpotVirtualMachine vm, String cmd, Object ... args)
      throws AgentLoadException, IOException
   {
      return vm.execute(cmd, args);
   }
}

Note: <jdkhome>/lib/tools.jar must be in classpath in order for the test program to compile and to be executed.

Usage: java -cp <jdkhome>/lib/tools.jar;. sun.tools.attach.AttachTester 278 1200 10 false:

278 = pid of jvm to attach
1200 = number of iterations to run
10 = sleeptime between iterations
false = don't execute version command

                                    

Comments
WORK AROUND

Periodically restart any client that uses the Windows attach API, by monitoring the number of allocated handles through the Windows Task Manager.
                                     
2007-05-18
EVALUATION

The description and fix is correct. It should only impact tools that use the Attach API over a very long period - tools such as jconsole, jstack, jmap, etc. should not be impacted as they are relatively short lived or only attach to a small number of VMs.
                                     
2007-05-18
SUGGESTED FIX

*** j2se/src/windows/native/sun/tools/attach/WindowsVirtualMachine.c~
--- j2se/src/windows/native/sun/tools/attach/WindowsVirtualMachine.c
***************
*** 431,436 ****
--- 431,437 ----
  		}
  	    }
  	}
+ 	CloseHandle(hThread);
      } else {
  	JNU_ThrowIOExceptionWithLastError(env, "CreateRemoteThread failed");
      }
                                     
2007-05-20



Hardware and Software, Engineered to Work Together