Android JNI编程提高篇之二

Chapter 7 Linear Voltage Regulators 这一章我们介绍LDO. 阅读详情
上文《 Android JNI编程提高篇之一 》中我和大家分享了局部引用的一些理解,本文我将继续和大家全局引用和弱全局引用的一些理解。这也可以作为我学习《 Java Native Interface: Programmer’s Guide and Specification 》一个总结,欢迎大家对本文的理解拍砖。

全局引用

    在所有引用中,我觉得全局引用是最好理解的一个了。为什么呢?主要和C语言的全局变量非常相近。

    上文《Android JNI编程提高篇之一》我已经提到局部引用大部分是通过JNI API返回而创建的,而全局引用必须要在Native代码中显示的调用JNI API NewGlobalRef来创建,创建之后将一直有效,直到显示的调用DeleteGlobalRef来删除这个全局引用。请注意NewGlobalRef的第二个参数,既可以用一个局部引用,也可以用全局引用生成一个全局引用,当然也可以用弱全局引用生成一个全局引用,但是这中情况有特殊的用途,后文会介绍。

    全局引用和局部引用一样,可以防止其指向的对象被Java虚拟机垃圾回收。与局部引用只在当前线程有效不同的是全局引用可以在多线程之间共享(如果是多线程编程需要注意同步问题)。

弱全局引用

    弱全局引用是非常让人迷惑的一个,主要是它的用法太怪异了。

    弱全局引用和全局引用一样,需要显示的创建和销毁。创建调用NewWeakGlobalRef,销毁调用DeleteWeakGlobalRef。

    与全局引用和局部引用能够阻止Java虚拟机垃圾回收其指向的对象不同,弱全局引用指向的对象随时都可以被Java虚拟机垃圾回收,所以使用弱全局变量的时候,要时刻记着:它所指向的对象可能已经被垃圾回收了。JNI API提供了引用比较函数IsSameObject,用弱全局引用和NULL进行比较,如果返回JNI_TRUE,则说明弱全局引用指向的对象已经被释放。需要重新初始化弱全局引用。根据上面的介绍你可能会写出如下的代码:

static jobject weak_global_ref = NULL;
if ((*env)->IsSameObject(env, weak_global_ref, NULL) == JNI_TRUE) {
    /* Init week global referrence again */
    weak_global_ref = NewWeakGlobalRef(...);
}

/* Process weak_global_ref */
.....

    上面这段代码表面上没有什么错误,但是我们忘了一点儿,Java虚拟机的垃圾回收随时都可能发生。假设如下情形:

    1、通过引用比较函数IsSameObject判断弱全局引用是否有效的时候,返回JNI_FALSE,证明其指向对象有效。

    2、这时Java虚拟机进行了垃圾回收,回收了弱全局引用指向的对象。

    3、这样如果我们后面访问弱全局引用指向的对象,将会引发程序崩溃,因为弱全局引用指向对象已经被Java虚拟机回收了。

    根据JNI标准手册《Weak Global References》中的介绍,我们可以有这样一个使用弱全局引用的方案。在使用全局引用之前,我们先通过NewLocalRef函数创建一个局部引用,然后使用这个局部引用来访问该对象进行处理,当完成处理之后,删除局部引用。局部引用可以阻止Java虚拟机回收其指向的对象,这样可以保证在处理期间弱全局引用和局部引用指向的对象不会被Java虚拟机回收。假如弱全局引用指向对象已经被Java虚拟机回收,则NewLocalRef函数将会返回NULL,则创建局部引用失败,这个返回值有助于我们判断是否需要重新初始化弱全局引用。我们可以写出如下的代码:

static jobject weak_global_ref = NULL;
jobject local_ref;

/* We ensure create local_ref success */、
while (week_global_ref == NULL || (local_ref = NewLocalRef(env, weak_global_ref)) == NULL ) {
    /* Init week global referrence again */
    weak_global_ref = NewWeakGlobalRef(...);
}

/* Process local_ref */
.....
(*env)->DeleteLocalRef(env, local_ref);

    注意在《Java Native Interface: Programmer’s Guide and Specification》的例子中,有很多不是按照如上的代码实现的,那些代码是有潜在风险的,请各位朋友注意。

    弱全局引用的有效期和全局引用一样,创建之后除非调用DeleteWeakGlobalRef显示的删除,否则将一直有效。并且弱全局引用可以在多个线程之间共享。

     你可能会问弱全局引用这么难用,为什么还要存在呢?Simon也觉得这个东西不好用,但是”存在即合理“,弱全局引用还是有他的用途的。弱全局引用是可以用来缓存jclass对象,那么你可能会问能否用全局引用来缓存jclass对象呢?答案是不可以。这里需要简单介绍一下Native的共享库的卸载。当Class Loader释放完所有的class后,然后Class Loader会卸载Native的共享库。如果我们用全局引用来缓存jclass对象的话,根据前面对全局引用对Java虚拟机垃圾回收机制的影响,将会阻止Java虚拟机回收该对象。则Class Loader也将不能释放这个jclass对象,进而造成Class Loader不能卸载Native的共享库(永远无法释放)。如果用弱全局引用来缓存将不会有这个问题,Java虚拟机随时都可以释放它指向的对象。

总结

    至此我们把JNI规范中的三种引用都进行了一个简单的介绍,在此我对以上内容做一个简单总结:

1、局部引用是Native代码中最常用的引用。大部分局部引用都是通过JNI API返回来创建,也可以通过调用NewLocalRef来创建。另外强烈建议Native函数返回值为局部引用。局部引用只在当前调用上下文中有效,所以局部引用不能用Native代码中的静态变量和全局变量来保存。另外时刻要记着Java虚拟机局部引用的个数是有限的,编程的时候强烈建议调用EnsureLocalCapacity和PushLocalFrame来确保Native代码能够获得足够的局部引用数量。

2、全局变量必须要通过NewGlobalRef创建,通过DeleteGlobalRef删除。主要用来缓存Field ID和Method ID。全局引用可以在多线程之间共享其指向的对象。在C语言中以静态变量和全局变量来保存。

3、全局引用和局部引用可以阻止Java虚拟机回收其指向的对象。

4、弱全局引用必须要通过NewWeakGlobalRef创建,通过DeleteWeakGlobalRef销毁。可以在多线程之间共享其指向的对象。在C语言中通过静态变量和全局变量来保持弱全局引用。弱全局引用指向的对象随时都可能会被Java虚拟机回收,所以使用的时候需要时刻注意检查其有效性。弱全局引用经常用来缓存jclass对象。

5、全局引用和弱全局引用可以在多线程中共享其指向对象,但是在多线程编程中需要注意多线程同步。强烈建议在JNI_OnLoad初始化全局引用和弱全局引用,然后在多线程中进行读全局引用和弱全局引用,这样不需要对全局引用和弱全局引用同步(只有读操作不会出现不一致情况)。

    本文和前文《Android JNI编程提高篇之一》是我对《Java Native Interface: Programmer’s Guide and Specification》学习的一个总结。只包括了我认为最难的引用部分,JNI编程还有很多其他方面需要学习的方面还很多,大家可以根据《Android JNI开发入门之一》介绍更深入的学习。希望我的这些博文对你学习JNI编程有所帮助。也欢迎JNI编程高手来拍砖。

转自:http://blog.youkuaiyun.com/gemmem/article/details/7290059

ubuntu恢复分区表——testdisk testdisk恢复ubuntu分区表testdisk介绍安装testdisk使用testdisk恢复分区表 testdisk介绍 testdisk 具有广泛的功能,包括恢复丢失或损坏的分区和使不能启动磁盘可以重新启动,也经常被用来恢复被误删的文件。 安装testdisk 如果系统分区表被删除,需要使用ubuntu的启动盘,选择try ubnutu模式进入试用系统。 1、可以直接在终端安装testdisk: sudo apt-get install testdisk 通过命令直接打开testdisk: t 阅读详情

相关推荐

一。CST 电路 微带低通滤波器设计练习 I

CST 电路和系统软件功能还是比较强的,我们一起一步一步学习,一起进步。 这个例子出现在CST的电路和系统软件功能(Circuit Simulation & SAM (System Assembly and Modeling) )介绍资料中。本文是用CST2021建模操作仿真到,不同版本在视觉和结果上稍有不同。 利用电路模块可以很快很准确地建立3D微带平面电路,用于仿真滤波器、功分器、巴伦等等。

麦克斯韦信徒的博客 3235

【Android NDK 开发】JNI 引用 ( 弱全局引用 | NewWeakGlobalRef | DeleteWeakGlobalRef )

I . 弱全局引用 II . 弱全局引用判定是否被回收 III . 弱全局引用 创建 与 删除 ( NewWeakGlobalRef | DeleteWeakGlobalRef ) IV . 弱全局引用代码示例

让 学习 成为一种 习惯 ( 韩曙亮 の 技术博客 ) 2319

电子元器件基础:电阻、电容、电感的特性与应用解析

本文深入解析了电子元器件中电阻、电容和电感三大基础元件的核心特性、工作原理与选型应用。电阻作为电路中的‘交通警察’,控制电流与分配电压,其额定功率与精度是关键选型参数。文章结合实战经验,详细阐述了它们在电源滤波、信号处理及高频电路中的不同表现与避坑指南,是电子设计与维修的必备基础知识。

weixin_29213655的博客 375

JNI内存管理之Local Reference 和 Global Reference知识点

最近开发过程中遇到了JNI的Reference相关问题,了解到Local Reference和Global Reference的相关知识点,整理如下: 背景:项目需求,在Native C/C++层调用上层Android Camera Java接口,把所有的操作包括Camera都沉到Native层去实现。但在JNI调试过程中遇到了android JNI ERROR (app bug): accessed stale local reference的报错。 现象:在Native层创建Java的Camera对象,

qq_29426201的博客 2538

别再死磕NFP了!用Python+遗传算法搞定异形件自动排版(附完整代码)

本文介绍了如何利用Python和遗传算法实现异形件智能排版,解决传统NFP方法计算复杂的问题。通过Shapely库处理几何运算和DEAP库搭建遗传算法框架,结合模拟退火策略避免局部最优,显著提升材料利用率。附完整代码和优化技巧,适用于服装裁剪、金属加工等行业。

weixin_26965807的博客 235

FLUENT UDF编译及蒸发冷凝相关问题

蒸发冷凝与相间传质

weixin_48029137的博客 1万+

[Java] [ Android ] [ JNI ] [ 局部引用、全局引用、弱全局引用 ] [ NewObject等、NewGlobalRef、NewWeakGlobalRef ]

1、局部引用,NewObject等众多接口返回的引用 下例以FindClass返回的引用,存储于全局变量中,或静态变量中。 第一次运行,创建,正常, 第二次之后,使用存储于全局变量的引用去操作,结果报异常 #include <jni.h> #include <string> // // Created by luohy on 2018/9/4. // /* Th...

Hendy_Raw的博客 3959

ResNet改进(51):基于轴向注意力机制的改进ResNet模型

本文介绍了一种结合轴向注意力机制的改进ResNet模型。 通过在传统CNN中引入轴向注意力,我们能够在保持计算效率的同时,增强模型对图像全局上下文的理解能力。这种混合架构结合了CNN的局部特征提取优势和注意力机制的全局建模能力,在图像识别任务中表现出色。 轴向注意力机制的应用不仅限于ResNet,也可以灵活地集成到其他CNN架构中。 未来可以探索更多注意力变体,或将其应用于特定领域任务,如医学图像分析、自动驾驶等需要精确空间理解的场景。 希望本文能帮助你理解如何将注意力机制与传统CNN结合,为你的计

2401_82355416的博客 357

Android JNI编程提高篇之一

[http://wenku.baidu.com/view/aeb61f3683c4bb4cf7ecd11b] Android JNI编程提高篇之一 Simon在拙文《Android JNI开发入门之二》中提到了,Android JNI开发的深入学习的一些资料和方法。最近Simon在学习《Java Native Interface:Programmer’s Guide and Spe

一头雾水的Blog 1585

从被秒封到稳过Cloudflare!Canvas/WebGL/WebRTC多维度浏览器指纹隐身全实战

反爬和反反爬,本质上是一场持续的博弈,没有100%的隐身,只有不断升级的伪装。网上很多教程只给了个基础的噪声代码,却没讲透反爬的检测逻辑,导致你用了还是被封。这套方案的核心,不是简单的API重写,而是站在反爬的角度,模拟真实用户的所有特征,保证所有指纹的一致性、合理性、完整性。目前这套方案我用了半年,跑了上千万次请求,稳过国内国外99%的主流反爬平台,没有出现过一次因为指纹关联导致的批量封禁。大家有什么更狠的反爬场景,或者更好的伪装技巧,欢迎评论区一起交流。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1193

在Simulink中搭建一个基于IoT设备间通信协议栈的仿真模型

物联网(IoT)设备间的通信协议栈仿真对于理解不同层级的协议如何协同工作,以及优化网络性能至关重要。通过Simulink结合MATLAB的强大功能,我们可以模拟和分析从物理层到应用层的完整通信过程。下面详细介绍如何使用Simulink进行IoT设备间通信协议栈的仿真。

amy_mhd的博客 156

Android JNI 高级编程

JNI作为java空间与C空间的沟通桥梁,在android中起到至关重要的作用。本文讲述jni的高级编程,需要有一定的jni基础,先分析了android源码中的jni编程模式,然后阐述一些实用的jni编程技巧。基础文章可以参考以下相关文章: Android NDK开发环境搭建 Android JNI概述 JNI各种类型转换总结         在android源码中,有

feifei 2115

2026年全国青少年信息素养大赛算法应用主题赛(C++赛项复赛模拟卷1:文末附答案)

2026年全国青少年信息素养大赛算法应用主题赛(C++赛项复赛模拟卷1:文末附答案)

王老师青少年编程 1611
上一篇: Android JNI开发入门之二
下一篇: Android JNI编程提高篇之一
HabbyGe
博客等级 码龄16年 46粉丝 143原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值