这个小文档是我两年前写的总结,在整理资料的时候翻了出来,又怕忘记了,所以贴在这里。 如果哪位同鞋能用的上的话,可以参考一下哈~ 这个是Java Native Interface编程中可能碰到的一个问题,
通过getJNIEnv() 获得的env需要在使用后及时释放,否则会造成java虚拟机的内存溢出,
可通过以下几种方法排除是否有未释放的内存空间。
JNIEnv* env = Android::AndroidRuntime::getJNIEnv();
例子1:
jstring japplication = env->NewString(application.characters(), application.length());
有New前缀的方法获得变量需要在使用后释放
例子2:
jclass mWidgetJS = env->FindClass("com/amt/widget/engine/jil/DeviceJni");
通过FindClass查找到的jclass需要在使用后释放
例子3:
jobject Configobject= env->CallStaticObjectMethod(mWidgetJS, mgetName);
通过Call调用函数得到的新的对象(不包括简单类型)需要在使用后释放
例子4:
jstring jsname=(jstring)env->CallStaticObjectMethod(mWidgetJS, mgetName,jnetworkConnecionType);
jsname原本应该释放(通过例子3可知),但是如果在执行过
to_string(env, jsname)后可不用再次释放,因为查看to_string函数后可知
WebCore::String to_string(JNIEnv* env, jstring str)
{
if (!str || !env)
return WebCore::String();
const jchar* s = env->GetStringChars(str, NULL);
if (!s)
return WebCore::String();
WebCore::String ret(s, env->GetStringLength(str));
env->ReleaseStringChars(str, s);
checkException(env);
return ret;
}
其中env->ReleaseStringChars(str, s);已经把jsname释放掉了。
例子5:
CallRecord* Telephony::getResult(JNIEnv* env, jobject callrecord)
其中callrecord是在调用getResult这个函数的时候传入进来的参数,所以不应该在本函数里
执行env->DeleteLocalRef(callrecord);而是在得到返回结果之后在调用此函数的函数里释放掉。
如果有疑问的地方可以找我.
by wei.han
附录:需要释放的对象类型(其中简单类型可不释放)
typedef _jobject* jobject;
typedef _jclass* jclass;
typedef _jstring* jstring;
typedef _jarray* jarray;
typedef _jobjectArray* jobjectArray;
typedef _jbooleanArray* jbooleanArray;
typedef _jbyteArray* jbyteArray;
typedef _jcharArray* jcharArray;
typedef _jshortArray* jshortArray;
typedef _jintArray* jintArray;
typedef _jlongArray* jlongArray;
typedef _jfloatArray* jfloatArray;
typedef _jdoubleArray* jdoubleArray;
typedef _jthrowable* jthrowable;
typedef _jobject* jweak;
转载地址: http://www.hiputto.com/post/2013-08-24/40053437304
|