Microsoft KB Archive/273728

= FIX: Garbage Collection Code Causes Access Violation in Long Running Java Applications =

Article ID: 273728

Article Last Modified on 6/14/2006

-

APPLIES TO


 * Microsoft Java 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 &quot;int 3&quot; 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:

http://www.microsoft.com/mscorp/java/

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 &quot;pin&quot; 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); }

