jni local refernces
来源:互联网 发布:浦发淘宝会员信用卡 编辑:程序博客网 时间:2024/05/21 17:04
So far, we have used data types such as
jobject
,jclass
, andjstring
to denote references toJava objects. However, the JNI creates references for all object argumentspassed to native methods, as well as all objects returned from JNIfunctions.References serve to keep the Java objects from being garbagecollected. By default, the JNI creates local references because local references ensure that the Java Virtual Machine can eventually free the Java objects. Local references become invalid when program execution returns from the native methodin which the local reference is created. Therefore, a native methodmust not store away a local reference and expect to reuse it insubsequent invocations.
For example, the following program, which is avariation of the native method in
FieldAccess.c
, mistakenly caches theJava class for the member variable ID so that it does not have to repeatedly searchfor the member variable ID based on the member variable name and signature at each invocation:This program is illegal because the local reference returned from/* This code is illegal */
static jclass cls = 0;
static jfieldID fld;
JNIEXPORT void JNICALL
Java_FieldAccess_accessFields(JNIEnv *env, jobject obj)
{
...
if (cls == 0) {
cls = (*env)->GetObjectClass(env, obj);
if (cls == 0) {
... /* error */
}
fid = (*env)->GetStaticFieldID(env, cls, "si", "I");
}
/* access the member variable using cls and fid */
...
}GetObjectClass
is valid only until the native method returns. When the Java application calls the native methodJava_FieldAccess_accessFields
a second time, the native method tries to use an invalidlocal reference. This leads to either the wrong results or to a VMcrash.You can overcome this problem by creating a globalreference. A global reference remains valid until it is explicitly freed. The following code rewrites the previous program and correctly uses a global reference to cache the class for the member variable ID:
/* This code is correct. */
static jclass cls = 0;
static jfieldID fld;
JNIEXPORT void JNICALL
Java_FieldAccess_accessFields(JNIEnv *env, jobject obj)
{
...
if (cls == 0) {
jclass cls1 = (*env)->GetObjectClass(env, obj);
if (cls1 == 0) {
... /* error */
}
cls = (*env)->NewGlobalRef(env, cls1);
if (cls == 0) {
... /* error */
}
fid = (*env)->GetStaticFieldID(env, cls, "si", "I");
}
/* access the member variable using cls and fid */
...
}A global reference keeps the Java Virtual Machine from unloading the Java class,and therefore also ensures that the member variable ID remains valid, as discussed in Accessing Java Member Variables. However, the native code must call
DeleteGlobalRef
when it nolonger needs access to the global reference. Otherwise, the Java Virtual Machine will never unload thecorresponding Java object, the Java class referenced bycls
above.In most cases, the native programmer should rely on the Java Virtual Machine to freeall local references after the native method returns. In certainsituations, however, the native code may need to call the
DeleteLocalRef
function to explicitly delete a local reference. These situations are:
- You may know that you are holding theonly reference to a large Java object and you do not want to wait untilthe current native method returns before the garbage collector can reclaim the object. For example, in the followingprogram segment, the garbage collector may be able to free the Javaobject referred to by
lref
when it is running insidelengthyComputation
:...
lref = ... /* a large Java object */
... /* last use of lref */
(*env)->DeleteLocalRef(env, lref);
lengthyComputation(); /* may take some time */
return; /* all local refs will now be freed */
}- You may need to create a large number of localreferences in a single native method invocation. This may result in anoverflow of the internal JNI local reference table. It is a good ideato delete those local references that will not be needed. For example,in the following program segment, the native code iterates through apotentially large array
arr
consisting of Java strings. After each iteration, the program can free the local reference to the stringelement:...
for(i = 0; i < len; i++) {
jstring jstr = (*env)->GetObjectArrayElement(env, arr, i);
... /* processes jstr */
(*env)->DeleteLocalRef(env, jstr); /* no longer needs jstr */
}
...
********************************************************
如果不显示的删除,可能会出现ReferenceTable overflow (max=512)
我曾出现这样的问题,LOG如下:
********************************************************
解决方法:(引自:http://hi.baidu.com/lihn1987/blog/item/73fb281ac1a61cdaac6e752c.html)
关于ReferenceTable overflow (max=512)的解决
最近遇到一个问题,晚上找了很久没有找到解决方法,最后自己琢磨解决了,特拿出来和大家分享,以免有人遇到同样的问题。
我的这个错误是这样产生的。我的程序大量使用java的jni功能,并在某些时候会频繁的java和C相互调用,这样在程序运行一段时间后就出现了题目中所说到的内容ReferenceTable overflow (max=512)。
从字面上我对这个错误的理解是这样的:java的垃圾处理里面有个叫引用计数的东东,我这里看到的错误貌似就是在说这个问题,引用计数表溢出?
于是我找了自己的代码,不停的屏蔽,发现错误竟然出现在c中调用java时候的这样一句话里
jc = (*ev)->GetObjectClass(m_obj);其中jc是javaclass的变量,难道是这句话有泄漏导致java的引用计数不停增加?又或者是这句话影响到了别的什么东西?
于是开始google,结果发现人家调用GetObjectClass的时候都调用啥子释放的东东啊,难道那个jc需要释放?????
自己找了n久发现在不用jc的时候调用m_env->DeleteLocalRef(jc);问题便解决了,嘎嘎
- jni local refernces
- JNI学习之-----Local and Global References
- Android:JNI Local Reference Changes in ICS
- Android:JNI Local Reference Changes in ICS
- JNI Local Reference Changes in ICS
- JNI 的 local reference table overflowed 问题
- android的 Local Socket 的JNI实现
- JNI Local Reference Changes in ICS
- JNI Local Reference Changes in ICS
- JNI--JNI ERROR (app bug): accessed stale local reference
- Failed to load the JNI shared library "/usr/local/jdk"
- JNI ERROR (app bug): accessed stale local reference
- JNI ERROR (app bug): accessed stale local reference
- jni 内存泄露 local reference table overflow (max=512)
- jni未释放资源问题。Failed adding to JNI local ref table (has 512 entries)
- JNI官方规范中文版——如何使用JNI中的global reference和local reference
- JNI学习三(Local references & Global references 以及JNI内存泄露)
- JNI官方规范中文版——如何使用JNI中的global reference和local reference
- 2011年信息安全展望
- Java通用分页【完整版】(一)
- javascript 与 applet 通讯
- 汇编程序设计 分支程序设计 拆半查找
- ubuntu iptables重定向
- jni local refernces
- 汇编编写的 冒泡排序
- VC2010 程序如何初始最大化
- java 通用分页【完整版】(二)
- linux下pdf转换成其它格式
- 一个可以再WIN2000及以上操作系统使用的GetTickCount64
- vista,windows7下删除隧道适配器(转)
- MFC获取汉字Unicode码
- struts2, 标签, s:iterator