У меня есть программа на C, которая хранит некоторый объект в хранилище java, используя JNI. (Прежде чем кто-то спросит, использование java store является обязательным требованием, и мне нужно написать клиент на C, который сможет добавлять и извлекать объекты из этого хранилища).
Я сделал программу и попытался добавить 100000 объектов размером 1 КБ. Но после добавления только 50000 объектов я получаю сообщения «из памяти» (обратите внимание, что я печатаю эти сообщения «из памяти» всякий раз, когда я не могу выделить новую строку или массив байтов с помощью функций NewStringUTF и NewByteArray). В то время мое приложение использует только 80 МБ памяти. Я не понимаю, почему эти методы возвращают NULL. Есть что-то, чего мне не хватает.
Кроме того, память продолжает увеличиваться, хотя я выпускаю байтовый массив и строку, созданные для Java.
Вот исходный код.
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);
}
}
Java-сторона получает данные в байте [] и сохраняет их в хеш-таблице.
Проблема в том, что при каждом запуске кода память только складывается и никогда не освобождается.
Я попытался добавить объект размером 1 МБ и отладил его.
Память процесса увеличивается на 1 МБ, когда я вызываю NewByteArray. Но когда вызывается CallStaticBooleanMethod, память процесса увеличивается на 4 МБ. И вызов ReleaseByteArrayElements вообще не освобождает память.
Если после этого я добавлю еще один объект размером 1 МБ, то память процесса останется такой же, когда я вызываю NewByteArray, и увеличится на 1 МБ при вызове CallStaticBooleanMethod, но останется такой же, когда я попытаюсь освободить массив байтов.