天天短讯!【GiraKoo】Java Native Interface(JNI)的空间(引用)管理
Java是通过垃圾回收机制回收内存,C/C++是通过malloc,free,new,delete手动管理空间。那么在JNI层,同时存在Java和C/C++的空间时,该如何进行空间的管理呢?本文参考Oracle的官方文档,对JNI层中空间的管理进行说明。明确哪些内容需要手动调用Delete,哪些不需要手动调用。
(相关资料图)
全局引用的生命周期(Lifetime),需要主动通过函数调用进行申请和释放。native函数执行完毕后,该空间可继续使用。
函数原型// 创建全局引用jobject NewGlobalRef(JNIEnv *env, jobject obj); // 删除全局引用void DeleteGlobalRef(JNIEnv *env, jobject globalRef);
二、局部引用(Local References)局部引用的生命周期(Lifetime),与调用的native函数一致。当native函数return时,局部引用将会被自动释放。该局部引用占用的空间是JVM的资源。
由于native函数用于存放局部引用的空间是固定的。如果过度的创建局部引用,不加以控制,可能会出现空间不足,程序抛出Out Of Memory(OOM)异常的问题。如果该局部引用已经使用完毕,应尽量手动调用DeleteLocalRef,提前释放空间,避免OOM。
函数原型// 创建全局引用jobject NewLocalRef(JNIEnv *env, jobject obj); // 删除全局引用void DeleteLocalRef(JNIEnv *env, jobject localRef);// 主动设置可创建的局部引用的数量jint EnsureLocalCapacity(JNIEnv *env, jint capacity);// 创建一个局部引用的帧,并指定可创建的局部引用的数量。jint PushLocalFrame(JNIEnv *env, jint capacity);// 释放当前局部引用的帧,释放全部本地引用。// 可以通过参数result,将被PopLocalFrame释放的引用转移到上一层的局部引用帧中jobject PopLocalFrame(JNIEnv *env, jobject result);
特殊说明在JDK/JRE 1.1版本中,提供了DeleteLocalRef
函数。在JDK/JRE 1.2版本中,提供了EnsureLocalCapacity
,PushLocalFrame
,PopLocalFrame
,NewLocalRef
函数,支持更加复杂的局部引用生命周期能力。三、弱全局引用(Weak Global Reference)区别于全局引用(Global References),该引用并不会增加该引用的引用计数。
即持有弱全局引用,不会干预垃圾回收机制(GC)对于该内存的回收。适用于生命周期短的对象,持有生命周期长的引用。
全局引用可以通过jboolean IsSameObject(JNIEnv *env, jobject ref1, jobject ref2);
函数,参数为被判定对象和NULL来判断对象是否存在。如果返回JNI_TRUE
判定该弱引用指向的对象是否已经被释放。
使用弱全局引用时,可能会出现执行一半,引用被GC回收的情况。所以需要在使用弱全局引用之前,提供NewLocalRef或者NewGlobalRef,将弱引用转换为强引用。确保GC不会对该空间进行回收。
四、常见问题1、在native函数中,直接return一个jstring或者其他jobject,是否会有内存泄漏问题?如果直接return的对象是局部引用(Local Reference),则不会发生内存泄漏问题。局部引用在native函数执行完毕后,会根据局部引用表(Local Reference Table)进行空间的释放。当然,手动执行DeleteLocalRef函数进行提前释放,也不会产生问题。
2、什么情况下可能会出现内存泄漏?1)创建的全局引用(Global Reference),未调用Delete函数进行回收。导致该对象引用计数无法归零。2)两个对象互相持有对方的强引用。例如A持有B引用,B和C互相持有对方的引用。当A释放B引用时,GC发现C依然持有B的引用,则不会释放B。与此同时,GC也发现B持有C的引用,则不会释放C。导致B和C与其他引用脱离,形成孤岛。这块内存将无法使用,也无法被释放。
3、调用NewString和NewStringUTF时,是否需要释放?NewString
和NewStringUTF
函数创建的空间属于局部引用(Local Reference)。可以等待native函数执行完毕后自动回收,也可以在使用完毕(后续不会再访问)后,直接进行Delete释放。
但是需要注意,如果通过GetStringChars
,GetStringCritical
或者GetStringUTFChars
获取了jstring中的char* 空间,则需要使用对应的ReleaseStringChars
,ReleaseStringCritical
或者ReleaseStringUTFChars
释放该char* 空间。
- 天天短讯!【GiraKoo】Java Native Interface(JNI)的空间(引用)管理
- 当前观察:世界首例泰坦尼克号3D全景扫描图像完成 探索沉船新发现
- 南阳:军地携手守护信息“生命线” 世界速看料
- 每日资讯:卫星导航与位置服务产业范围扩大 总体产值同比增长6.76%
- 有钱有闲的中产阶级在玩高尔夫?选择方便适合自己的运动就OK!
- 超10亿元押金还没退,小黄车创始人戴威却去美国开咖啡厅!
- 阆中农商银行下乡开展存款保险知识宣传
- 国家医保局:严厉打击各种违规违法使用医保基金的行为绝不让医保基金成为“唐僧肉”
- 从UU跑腿到蜜雪冰城 郑州金水为何能不断崛起消费“新势力”|豫观察|环球热头条
- 焦点报道:【中国式现代化的长三角实践】创新开发模式 让“江南第一村”“活起来”
- 观点 | 国际原油和有色金属价格维持振荡走势-当前速递
- 因地制宜发展富民产业
- 超高待遇!戛纳电影节红毯为巩俐清场5分钟 环球速递
- 孙中山介绍资料_孙中山个人简介 每日快看
- 天天微头条丨网卡驱动下载详细教程
- 全球快看:Beats Studio Buds+发布 透明配色更亮眼售价1349元
- 【环球快播报】好习惯手抄报_好习惯儿歌
- 全球观热点:广州活动优惠新楼盘有哪些?值不值得买?
- 13万亿美元未兑现!G7被批给“全球南方”开空头支票
- 消息!首款V12混动超跑 兰博基尼Revuelto静态体验
- 世界关注:深交所向山水比德发出问询函
- 百度登记文心大模型相关著作权
- 世界热消息:四时田园杂兴古诗意思其三十一的中心思想
- 每日简讯:教师专业发展定义_教师的定义
- 【央广时评】把握消费升级新机遇 展现中国经济高质量发展信心
- 当前热讯:中消协:消费领域仍存四方面突出问题
- 利用IBM Watson Code Assistant重塑IT自动化|焦点消息
- 大连到沈阳高铁路线_大连到沈阳高铁路线概述 世界快资讯
- 腾讯:一季度本土市场游戏收入增长6%至351亿元
- 今日热讯:汽车进气压力传感器工作原理_进气压力传感器工作原理