Microsoft SDK for Java

Garbage Collection Issues

The following topics describe the issues associated with garbage collection:

Protecting Objects on the Stack
Protecting Objects in Allocated Memory
Calling Back To Java

Protecting Objects on the Stack

By default, garbage collection cannot occur while native code is executing. Other threads that try to do any garbage collection will block until the thread in native code returns to Java. This allows the virtual machine to avoid conservative scanning of native stacks, which is often unreliable and can slow down performance.

A lot of native code does some quick calculation and returns, so this isn't a problem. However, if the native code is going to perform an operation that takes some time, explicitly enable and disable garbage collection around the slow code.

Of course, enabling garbage collection means that any object could move at any time, invalidating any pointers to those objects in native code. The simplest way to handle this is to inform the garbage collector of objects you're interested in before enabling garbage collection using a GCFrame with GCFramePush. Object pointers kept in a GCFrame will be automatically updated if the object gets moved. When you're done, inform the garbage collector using GCFramePop. The following is a typical example:

void some_java_method(HObject *phobj1Unsafe, HObject *phobj2Unsafe)
{
// Keep a structure with all the objects we're interested in.
struct
{
HObject *phobj1Safe;
HObject *phobj2Safe;
} gc;

// Declare a GCFrame;
GCFrame gcf;

// Tell the garbage collector about our structure. 
// It will initialize this structure to null.
GCFramePush(&gcf, &gc, sizeof(gc));

// Set the object ptr.
gc.phobj1Safe = phobj1Unsafe;
gc.phobj2Safe = phobj2Unsafe;

// It's now safe to enable garbage collection.
GCEnable();

// ...time passes...garbage collection occurs...objects move...

// Disable gargbage collection so we can access objects safely.
GCDisable();

// If garbage collection moved our object,
// then gc.hobjSafe will have been automatically updated.

gc.phobj1Safe->x = 42;
gc.phobj2Safe->y = 33;

// We're done.
GCFramePop(&gcf);
}

Note   

Protecting Objects in Allocated Memory

GCFrames are ideal for protecting objects on the stack, but not in situations where you want to keep an object pointer longer than the lifetime of the function in global memory. For situations like this, use GCNewHandle and GCFreeHandle instead as follows:

    HObject **pphobjSafe = NULL;

    void some_java_methodA(HObject *phobjUnsafe)
    {
        // Allocate a strong ptr that we want to use later.
        pphobjSafe = GCNewHandle(phobjUnsafe);
    }

    void some_java_methodB()
    {
        // Use the strong ptr we saved previously.
        *pphobjSafe->x = 42;
        GCFreeHandle(pphobjSafe);
    }

You can also create "weak" pointers to track an object’s movement by calling GCGetPtr. A weak pointer allows the tracked object to be freed by the garbage collector if no more references to that object exist. After the tracked object is freed by the garbage collector, the contained pointer will be NULL. Do not call GCFreePtr on a weak pointer to a freed object. If you know the tracked object has not been freed by the garbage collector, call GCFreePtr when you no longer need to keep track of it.

Calling Back To Java

If you call back to Java from native code, garbage collection may automatically be enabled by the Microsoft VM if memory needs to be allocated. This means that any object pointer you want to use after the call must be protected, either in a GCFrame or tracked by a strong pointer.

© 1999 Microsoft Corporation. All rights reserved. Terms of use.