Memory leak when calling java code from C using JNI


Joined
Aug 28, 2009
Messages
2
Reaction score
0
Hi, I have a C program that stores some object in java store using JNI. (Before someone ask, using java store is a requirement here and I have to write a client in C which would be able to add and retrieve objects from this store).

I made the program and tried to add 100000 object of size 1KB. But after adding only 50000 objects I am getting 'out of memory' messages (please note that I am printing these 'out of memory' messages whenever I am unable to allocate a new string or byte array using NewStringUTF and NewByteArray functions). At that time my application is using only 80MB of memory. I don’t why these methods are returning NULL. Is there something I am missing?

Furthermore, the memory keeps on increasing even though I am releasing byte array and string created for java.

Here is the source code.

Code:
void create_jvm(void)
{
        JavaVMInitArgs vm_args;         
        JavaVMOption vm_options;

        vm_options.optionString = "-Djava.class.path=c:\\Store";
        vm_args.version = JNI_VERSION_1_4;
        vm_args.nOptions = 1;
        vm_args.options = &vm_options;
        vm_args.ignoreUnrecognized = 0;

        JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);

        if(env != null)
        {
                j_store = (*env)->FindClass(env, "com/store");
                if(j_store == null)
                {
                        printf("unable to find class. class name: JStore");
                }               
        }       
}

void add(char* key, char* value, int length)
{
        jstring j_key = (*env)->NewStringUTF(env, key);
        jbyteArray j_value = (*env)->NewByteArray(env, length);

        (*env)->SetByteArrayRegion(env, j_value, 0, length, (jbyte *)value);
        ret = (*env)->CallStaticBooleanMethod(env, j_store, method_id, j_key, j_value);

        if(j_value != null)
        {
                (*env)->ReleaseByteArrayElements(env, j_value, (jbyte *)value, 0);
        }
        if(j_key != null)
        {
                (*env)->ReleaseStringUTFChars(env, j_key, key);
        }
}

The java side receives the data in byte[] and stores it in a hashtable. The issue is that every time the code runs the memory only adds up and is never released. I tried to add 1 MB object and debugged it. Here is what happened.

The process memory increases by 1MB when I call NewByteArray. But when CallStaticBooleanMethod is called the process memory increase by 4MB. And the call to ReleaseByteArrayElements do not release any memory at all.

If I add another 1MB object after this, then process memory remains same when I call NewByteArray and it increase by 1MB when I call CallStaticBooleanMethod but remains the same when I try to release the byte array.

On java side, though I am receiving a byte[], the value is first serialized and then saved to a Hashtable (Serialization is part of requirement as the data may no always be in byte[] form and can be stored on disk or in another process)

Can someone help me in identifying the problem?
 
Ad

Advertisements


Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top