FIX: Garbage Collection Code Causes Access Violation in Long Running Java Applications (273728)



The information in this article applies to:

  • Microsoft virtual machine

This article was previously published under Q273728

SYMPTOMS

Long running Java applications on the Microsoft virtual machine (Microsoft VM) may encounter an access violation, which shuts down the process.

CAUSE

This is caused by a bug in the garbage collection code of the Microsoft VM. One way to identify this is when a debugger is attached to the process, it may first break at a hardcoded "int 3" in Msjava.dll.

RESOLUTION

To resolve this issue, install build 3318 or later of the Microsoft VM. For more information, visit the following Microsoft Web site: WARNING: After you install the updated Microsoft VM, you cannot uninstall it.

STATUS

Microsoft has confirmed that this is a problem in the Microsoft products that are listed at the beginning of this article.

MORE INFORMATION

You encounter this problem only if applications allocate more than 16 megabytes of objects (which is measured by calling the java.lang.Runtime.totalMemory method) and "pin" two or more objects, either explicitly or implicitly. A pinned object is an object that the garbage collector cannot move in memory. To explicitly pin objects, you can use the GCNewPinnedHandle Raw Native Interface (RNI) API from native code or the com.ms.dll.DllLib.getPinnedHandle method from Java code. Primitive arrays are implicitly pinned when they are used as parameters in J/Direct or Java/COM methods.

To work around this problem, avoid explicitly pinning objects, and change calls to J/Direct and Java/COM methods that have primitive arrays as parameters to explicitly allocate arrays using the com.ms.dll.DllLib.allocHGlobal method. The allocated array would then be passed as an int parameter to the J/Direct or Java/COM method. The following code illustrates this change.

Change the following code from
/** @dll.import(???) */ 
static native void JDirectMethod (byte[] rgb);

void Test ()
{
   byte[] rgb = new byte[10];
   JDirectMethod(rgb);
}
				

to either:
/** @dll.import(???) */ 
static native void JDirectMethod (int rgb);

void Test ()
{
   int rgb = DllLib.allocHGlobal(10);

   JDirectMethod(rgb);

   DllLib.freeHGlobal(rgb);
}
				

or:
/** @dll.import(???) */ 
static native void JDirectMethod_Worker (int rgbPointer);

static void JDirectMethod (byte[] rgbObject)
{
   int cb = rgbObject.length;
   int rgbPointer = DllLib.allocHGlobal(cb);

   DllLib.copy(rgbObject, 0, rgbPointer, cb);

   JDirectMethod_Worker(rgbPointer);

   DllLib.freeHGlobal(rgbPointer);
}

void Test ()
{
   byte[] rgb = new byte[10];

   JDirectMethod(rgb);
}
				

REFERENCES

For support information about Visual J++ and the SDK for Java, visit the following Microsoft Web site:

Modification Type:MajorLast Reviewed:6/14/2006
Keywords:kbBug kbfix kbGarbageCollect kbJavaVM33xxfix kbOSWin2000fix KB273728