NDK开发与实践(入门篇微课视频版)

news/2025/10/6 10:26:50/文章来源:https://www.cnblogs.com/dslw0820/p/19127361

9.3 DirectBuffer的使用场景
当使用byte[]数组时,Java代码需要将数据从Java堆复制到原生内存(例如,通过JNI的SetByteArrayRegion()或GetByteArrayRegion()函数),然后原生代码才能访问这些数据。这种数据复制操作可能会带来额外的性能开销。在某些实现中,可以使用GetByteArrayElements()和 GetPrimitiveArrayCritical()函数获取指向托管堆中原始数据的实际指针,但在其他实现中,它会在原生堆上分配缓冲区并复制数据,所以,byte[]传递是否能获得真正的原始数据的指针,取决于虚拟机的实现,而直接字节缓冲区允许原生代码直接访问其内存区域,无须进行这种复制操作。
9.3.1 大数据量的IO密集型操作
对于需要处理大量数据的IO密集操作,如文件读写、网络通信等,DirectBuffer可以
显著提高性能。由于DirectBuffer的内存分配在JVM堆外,因此可以避免在Java堆内存和操作系统之间复制数据的需要,从而减少了数据处理的时间和CPU的负载。
9.3.2 长期使用的数据
对于那些需要长期使用的数据,使用DirectBuffer可以避免频繁地创建和销毁堆内
Buffer所带来的额外开销。由于DirectBuffer的生命周期内的内存地址都不会再发生更改,因此内核可以安全地对其进行访问。
9.3.3 对内存管理有特殊要求的场景
DirectBuffer的使用降低了垃圾收集的压力,因为它们不受JVM垃圾收集的直接管
理。这在一些对内存管理有特殊要求的场景中可能非常有用,例如需要避免频繁垃圾收集导致的性能波动或延迟。

9.3.4 需要直接访问操作系统内存资源的场景
DirectBuffer提供了一种高效的方式来直接访问和操作系统级别的内存资源。这种方式允许Java应用程序能够更接近操作系统的底层,提供了更为高效的数据处理能力。

9.4 DirectBuffer的使用案例
示例代码将演示在原生代码中申请缓冲区,并通过JNI接口使其可被Java代码访问。在Java端,利用获得到的缓冲区的引用将数据高效地传递到原生代码中。同时,示例代码将记录两种传递方式分别运行10000000次的耗时。

代码如下:
//第9章/MainActivity.java
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
static {
System.loadLibrary("directbuffer");
}

ByteBuffer mByteBuffer;
@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//获得native中申请的缓冲区mByteBuffer = getNativeByteBuffer();//申请一个byte数组byte[] bytes = new byte[10240];//初始化数组内容for (int i = 0; i < 10240; i++) {bytes[i] = (byte) i;}//将byte数组放到bytebuffer中mByteBuffer.put(bytes);int count = 10000000;//打印时间Log.e(TAG, "onCreate: sendData start time: "  + SystemClock.currentThreadTimeMillis());while (count > 0){//通知原生代码操作数据sendData();count --;}Log.e(TAG, "onCreate: sendData end time: "  + SystemClock.currentThreadTimeMillis());count = 1000000;//打印时间Log.e(TAG, "onCreate: setByteData start time: "  + SystemClock.currentThreadTimeMillis());while (count > 0){//将byte[]传递到原生代码中setByteData(bytes);count --;}Log.e(TAG, "onCreate: setByteData end time: "  + SystemClock.currentThreadTimeMillis());
}/*** 获取native申请的DirectBuffer* @return  DirectBuffer*/
public native ByteBuffer getNativeByteBuffer();/*** 通知原生代码操作数据*/
public native void sendData();/*** 使用byte[]数组传递方式* @param data byte[]*/
public native void setByteData(byte[] data);

}

原生代码实现代码如下:
//第9章/native-lib.c

include <jni.h>

include <string.h>

include <malloc.h>

include <android/log.h> //添加头文件

define LOG_TAG "jni" //定义TAG

define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, VA_ARGS)

unsigned char *gl_buffer = NULL; //DirectBuffer地址
unsigned int gl_capacity; //DirectBuffer 容量

unsigned char buffer[10240] = {0}; //用来模拟数据的复制

JNIEXPORT jobject JNICALL
Java_com_example_directbuffer_MainActivity_getNativeByteBuffer(JNIEnv *env, jobject thiz) {
if (NULL == gl_buffer){
gl_buffer = malloc(10240);
}

return (*env)->NewDirectByteBuffer(env, gl_buffer, 10240);

}

JNIEXPORT void JNICALL
Java_com_example_directbuffer_MainActivity_sendData(JNIEnv *env, jobject thiz) {
//由于是DirectBuffer,这里可以直接使用gl_buffer,无须复制
}

JNIEXPORT void JNICALL
Java_com_example_directbuffer_MainActivity_setByteData(JNIEnv env, jobject thiz, jbyteArray data) {
//模拟数据的使用,将数组内容复制到gl_buffer中才能使用
(
env)->GetByteArrayRegion(env, data, 0, 10240, gl_buffer);
}

运行结果如下:

//使用DirectBuffer,10000000次执行耗时66ms
sendData start time: 117
sendData end time: 183

//直接传递byte[],10000000次执行耗时2021ms
setByteData start time: 183
setByteData end time: 2204

对于不同次数比较的运行结果,见表9-1。

表 9 1 运行结果比较
运行次数 DirectBuffer byte[] 差值(ms)
1000 0 0 0
10000 3 4 1
100000 12 24 12
1000000 18 208 190
10000000 66 2021 1955

从运行结果可以看出,随着运行次数的增加,相较于使用byte[],使用DirectBuffer对性能的提升也就越明显。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/929214.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【深度学习优化算法】02:凸性 - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

温州通业建设工程有限公司网站深圳网站建站的公司

Git学习笔记 文章目录 Git学习笔记一、版本控制二、Linux基础命令三、Git的环境配置四、Git的基本理论&#xff08;核心&#xff09;五、Git项目的搭建六、Git文件操作七、使用码云八、IDEA集成git九、Git分支 一、版本控制 什么是版本控制 版本控制&#xff08;Revision contr…

调了很久的代码总结

凡是在循环前面加了特判的东西,都要检查一下循环内部要不要判。 可以再读一遍题来调代码。

在Windows上搭建 EasyTier 公共服务器

在Windows上搭建 EasyTier 公共服务器2024.10.01 关于本教程 本教程将介绍如何在Windows上搭建 EasyTier 公共服务器 以帮助那些无公网的节点进行连接 值得注意的是EasyTier是不区分客户端和服务端的 其本身同时承载 服…

Transformer模型开发从0到1——原理深入与项目实践

本书分为5篇共17章。Transformer模型基础篇(第1~5章)重点介绍Transformer模型框架。把Transformer模型掰开,从最基础的输入出发,按照模型框架,一点一点走进Transformer模型的内部,直到最终的模型输出;Transform…

常州品牌网站建设免费文字变形logo设计

在软件工程中&#xff0c;设计模式是为了解决常见的软件设计问题而形成的一套经典解决方案。这些模式不仅能够帮助开发者提高设计的灵活性和代码的重用性&#xff0c;还能使问题的解决方案更加清晰、易于理解。《设计模式精解&#xff0d;GoF 23种设计模式》一书中所列举的23种…

毕业设计 网站开发简单吗蘑菇街网站模板

最近偶尔有用户反馈某些 HTTP 接口出现超时问题&#xff0c;而 web 服务端的 Trace 监控没有出现 http 返回值为 503 等异常情况。出现这种情况一般是web容器出现问题&#xff0c;客户端连 Arthas是Alibaba开源的Java诊断工具&#xff0c;深受开发者喜爱。 Github&#xff1a;h…

鸿蒙OS基于UniApp的区块链钱包创建实践:打造支持鸿蒙生态的Web3应用#三方框架 #Uniapp

鸿蒙OS&基于UniApp的区块链钱包创建实践:打造支持鸿蒙生态的Web3应用#三方框架 #Uniapppre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !impor…

CF700E

题目大意: 给定一个长为 \(n\) 的字符串 \(S\),你要找到最大的 \(k\),使得存在 \(s_{1} \sim s_{k}\) 使得 \(s_{1}\) 是 \(S\) 子串 且 \(s_{i}\) 在 \(s_{i - 1}\) 中作为子串至少出现两次。 \(n \le 2 \times 10…

价值弥漫:“AI元人文”的场域革命与共生之路

价值弥漫:“AI元人文”的场域革命与共生之路 本文探讨“价值弥漫”作为“AI元人文”核心实现路径的哲学基础与技术内涵,提出从“工具性AI”到“场域性AI”的范式转变。 引言:从“价值对齐”到“价值弥漫”的范式迁移…

手机app设计网站公司网站建设需要什么科目

流程图 一、前期准备 1.1 打开百度智能云官网找到管理中心创建应用 全选文字识别 1.2 保存好AppId、API Key和Secret Key 1.3 找到通用场景文字识别&#xff0c;立即使用 1.4 根据自己需要&#xff0c;选择要开通的项目 二、代码编写 以通用文字识别&#xff08;高精度版&am…

k8s之pod概念

1. pod基本概念 2. pod网络概念 3. pod的生命周期和状态 4. 探针 5. 创建pod 6. 总结‍ 1. pod基本概念Kubernetes 中,Pod 是最小的网络调度单位, 每个pod可以放多个容器(例如可以放多个docke容器在同一个pod中运行…

鸿蒙版Taro 搭建开发环境 - 教程

鸿蒙版Taro 搭建开发环境 - 教程2025-10-06 10:09 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !import…

CF 1055 Div.1+Div.2

F - Triple Attack 我会了。 G - Query Jungle 我会了。 H1 - Victorious Coloring (Easy Version) 我不会。 H2 - Victorious Coloring (Hard Version) 我不会。

LUCKY STUN穿透在Windows上使用UPnP工具为BT客户端自动添加内外端口号不同的映射规则

LUCKY STUN穿透在Windows上使用UPnP工具为BT客户端自动添加内外端口号不同的映射规则2024.02.07 关于本教程 本教程基于:基于stun穿透工具LUCKY,使BT客户端绿灯、开放TCP端口的办法(进化版) 在该教程中实现了使用 …

深圳门户网站制作wordpress 鼠标特效

摘要&#xff1a; 4月30日&#xff0c;阿里云发现&#xff0c;俄罗斯黑客利用Hadoop Yarn资源管理系统REST API未授权访问漏洞进行攻击。 Hadoop是一款由Apache基金会推出的分布式系统框架&#xff0c;它通过著名的 MapReduce 算法进行分布式处理&#xff0c;Yarn是Hadoop集群的…

2026 NOI 做题记录(五)

推荐阅读:A、B、E、F、N、O、R、T、U、WContest Link \(\text{By DaiRuiChen007}\)*A. [CF2097F] Lost Luggage (7.5) Problem Link 先建立网络流,每层的点 \(i\) 向下一层 \(i-1,i,i+1\) 分别连权值 \(a_i,b_i,c_i\…

ARC 207 (Div.1)

A - Affinity for Artifacts 我不会。我会了。 B - Balanced Neighbors 2然后 \(n\leq 5\) 无解。 C - Combine to Make Non-decreasing 容易发现原题目等价于将原序列分成若干段,要求段之间的 \(\text{OR}\) 值 non-…

四大门户网站的区别深圳营销型网站定制

教师资格认定前需要做的准备材料 准备身份证户口本 居住证 学生证 教师考试合格证明 普通话证书 学历证书 体检合格证书 近期一寸白底证件照 网上报名 河南24下教资认定 网上报名时间&#xff1a;10月21日-11月1日 现场确认 网上审核未通过的宝子&#xff0c;需要…

“齐俊杰投资智能体”更新完了9月份的资料

“齐俊杰投资智能体”更新完了9月份的资料,本次更新包括了9月份的课程和粉丝群问答,读书更新了这几本:明斯基时刻。每日问答的语音转文字已经使用了AI进行格式优化,更加容易阅读。将新资料更新到了智能体,大家可以…