Java C内存泄漏问题,valgrind测试(JNI)
我通过JNI调用JAVA中的C库来使用它。我注意到内存大小不断增加,并决定使用valgrind检查内存泄漏 这是我从Java调用的代码片段Java C内存泄漏问题,valgrind测试(JNI),java,c,memory-leaks,java-native-interface,valgrind,Java,C,Memory Leaks,Java Native Interface,Valgrind,我通过JNI调用JAVA中的C库来使用它。我注意到内存大小不断增加,并决定使用valgrind检查内存泄漏 这是我从Java调用的代码片段 JNIEXPORT jstring JNICALL Java_GenderService_genderize (JNIEnv *env, jobject obj, jstring string) { const char *str = (*env)->GetStringUTFChars(env, string, 0); char
JNIEXPORT jstring JNICALL Java_GenderService_genderize
(JNIEnv *env, jobject obj, jstring string)
{
const char *str = (*env)->GetStringUTFChars(env, string, 0);
char cap[128];
strcpy(cap, str);
(*env)->ReleaseStringUTFChars(env, string, str);
int gender = get_gender_utf8 (cap,
GENDER_COMPARE_EXPANDED_UMLAUTS, GENDER_DEFAULT_COUNTRY);
char* s;
switch (gender)
{
case IS_FEMALE : s = "FEMALE"; break;
case IS_MOSTLY_FEMALE : s = "MOSTLY_FEMALE"; break;
case IS_MALE : s = "MALE"; break;
case IS_MOSTLY_MALE : s = "MOSTLY_MALE"; break;
case IS_A_COUPLE : s = "COUPLE"; break;
case IS_UNISEX_NAME : s = "UNISEX"; break;
case EQUIVALENT_NAMES : s = "names are equivalent"; break;
case NOT_EQUAL_NAMES : s = "names are not equal"; break;
case NAME_NOT_FOUND : s = "NAME_NOT_FOUND"; break;
case ERROR_IN_NAME : s = "ERROR_IN_NAME"; break;
case INTERNAL_ERROR_GENDER : s = "INTERNAL_ERROR"; break;
default : s = "UNKNOWN_ERROR"; break;
}
return (*env)->NewStringUTF(env, s);
}
我独立地测试了get_gender_utf8方法,将其包装在main中并使用valgrind调用,结果没有发现泄漏
int main (int argc, char *argv[])
{
char cap[128];
strcpy(cap, argv[1]);
int i = get_gender_utf8 (cap,
GENDER_COMPARE_EXPANDED_UMLAUTS, GENDER_DEFAULT_COUNTRY);
printf("%d", i);
char* s;
s = "FEMALE";
return (0);
}
=
=
这是否意味着泄漏在这些管线的某个地方
const char *str = (*env)->GetStringUTFChars(env, string, 0);
char cap[128];
strcpy(cap, str);
(*env)->ReleaseStringUTFChars(env, string, str);
char* s;
return (*env)->NewStringUTF(env, s);
频繁的完整GC日志
434711.391: [Full GC 463295K->463264K(463296K), 1.4745520 secs]
434712.868: [Full GC 463296K->463264K(463296K), 1.4686460 secs]
434724.339: [Full GC 463295K->463264K(463296K), 1.5353370 secs]
434735.877: [Full GC 463295K->463264K(463296K), 1.5300430 secs]
434737.409: [Full GC 463296K->463264K(463296K), 1.4186100 secs]
434748.830: [Full GC 463295K->463265K(463296K), 1.6480810 secs]
434760.481: [Full GC 463295K->463264K(463296K), 1.4662190 secs]
434771.949: [Full GC 463295K->463264K(463296K), 1.4691700 secs]
434773.420: [Full GC 463295K->463265K(463296K), 1.4697440 secs]
434784.893: [Full GC 463295K->463264K(463296K), 1.6079780 secs]
434796.502: [Full GC 463295K->463264K(463296K), 1.5225740 secs]
434798.027: [Full GC 463295K->463265K(463296K), 1.3949160 secs]
谢谢你的帮助和建议 也许这会有所帮助:您检查过JavaGC输出了吗?Java虚拟机喜欢不断增加占用空间,除非达到极限……我看不出您的代码有什么问题。正如Valeri提到的,JVM本身可能在NewStringUTF内部或其他地方分配内存,但没有及时释放内存,因为GC就是这样做的。我添加了GC日志@喘息,你所说的GC是什么意思?你认为我能解决问题吗?我发现这个问题可以用DeleteLocalRef解决,这对您有意义吗?我的意思是,GC可以在释放内存后的任何时候自由地完成和回收内存,或者永远不会,因为它认为合适。valgrind的运行级别低于JVM,因此,即使JVM在java模型中释放了一些内存,但这并不意味着它会将包含的原始块释放回操作系统——它通常会保留这些原始块,并将其回收以供以后使用。
434711.391: [Full GC 463295K->463264K(463296K), 1.4745520 secs]
434712.868: [Full GC 463296K->463264K(463296K), 1.4686460 secs]
434724.339: [Full GC 463295K->463264K(463296K), 1.5353370 secs]
434735.877: [Full GC 463295K->463264K(463296K), 1.5300430 secs]
434737.409: [Full GC 463296K->463264K(463296K), 1.4186100 secs]
434748.830: [Full GC 463295K->463265K(463296K), 1.6480810 secs]
434760.481: [Full GC 463295K->463264K(463296K), 1.4662190 secs]
434771.949: [Full GC 463295K->463264K(463296K), 1.4691700 secs]
434773.420: [Full GC 463295K->463265K(463296K), 1.4697440 secs]
434784.893: [Full GC 463295K->463264K(463296K), 1.6079780 secs]
434796.502: [Full GC 463295K->463264K(463296K), 1.5225740 secs]
434798.027: [Full GC 463295K->463265K(463296K), 1.3949160 secs]