Android开发Bitmap在Native层与Java层内存的两种生成方式
2014-08-26 14:24
369 查看
忽略掉遥远的Android2.2及之前版本,本文讨论基于Android4.4,也适用于4.x版本。
项目开发中遇到一个内存溢出问题,抓内存数据分析,发现有的bitmap在java层生成,占用的Dalvik虚拟机堆栈,这也符合我当前粗略的认知,恕本人知识浅陋。原来研究内存,一直认为Android2.2之后的各个版本Android中bitmap都是通过JNI回调到Java层,最后是在Java层真正new出来的bitmap(这个在本文最后取源码做了说明)。可是抓到的信息发现了一个Native stack上的Bitmap,如下图所示。
然后查看资料和源码发现,的确这个是在Native Stack上创建的,因为它是调用BitmapFactory.decodeStream方法,创建出一个bitmap,decodeStream直接调用 JNI 的 nativeDecodeAsset() 来完成decode,这点不同于使用java层的createBitmap。所以这个是在Native层占用的内存。
private static Bitmap readBitMap(Context context, int resId) {
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inPreferredConfig = Bitmap.Config.RGB_565;
opt.inPurgeable = true;
opt.inInputShareable = true;
// 获取资源图片
InputStream is = context.getResources().openRawResource(resId);
return BitmapFactory.decodeStream(is, null, opt);
}
这里代码搬一下别人的代码来说明,如何做就在Native层生成Bitmap了,如上代码,Options需要设置两个参数, inPurgeable 、inInputShareable为true。其实看源码分析,如果调用decodeStream方法,其实只要 inPurgeable
为true就够了,inInputShareable是默认为true的,不过别的方法就需要双双为ture,稍后源码分析详述此处。大家只要如上调用就可以让bitmap在Native上了。具体性能会不会有影响,稍后我会写几个demo验证一下。
如图就是源码中的调用,图为BitmapFactory这个源码中decodeStream方法的具体实现,我们可以看到是调用的Native方法,可能有人会问了如果走了else呢,其实else里面的方法跟进去就会发现,也是做了一些处理后,调用nativeDecodeAsset来生成的bitmap。
说到这里我们必须说一个重要的事情,大家千万别以为去调用Native方法就一定是在Native层占用的内存,例如Bitmap.java中的createBitmap也是调用的JNI方法,但其实又反过来回调的Java中的New来做的生成操作。具体的这个地方,我会专门写一篇文章来讲Bitmap和BitmapFactory的源码,从源码中彻底分析一下为什么就是在Native中生成的。
项目开发中遇到一个内存溢出问题,抓内存数据分析,发现有的bitmap在java层生成,占用的Dalvik虚拟机堆栈,这也符合我当前粗略的认知,恕本人知识浅陋。原来研究内存,一直认为Android2.2之后的各个版本Android中bitmap都是通过JNI回调到Java层,最后是在Java层真正new出来的bitmap(这个在本文最后取源码做了说明)。可是抓到的信息发现了一个Native stack上的Bitmap,如下图所示。
然后查看资料和源码发现,的确这个是在Native Stack上创建的,因为它是调用BitmapFactory.decodeStream方法,创建出一个bitmap,decodeStream直接调用 JNI 的 nativeDecodeAsset() 来完成decode,这点不同于使用java层的createBitmap。所以这个是在Native层占用的内存。
private static Bitmap readBitMap(Context context, int resId) {
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inPreferredConfig = Bitmap.Config.RGB_565;
opt.inPurgeable = true;
opt.inInputShareable = true;
// 获取资源图片
InputStream is = context.getResources().openRawResource(resId);
return BitmapFactory.decodeStream(is, null, opt);
}
这里代码搬一下别人的代码来说明,如何做就在Native层生成Bitmap了,如上代码,Options需要设置两个参数, inPurgeable 、inInputShareable为true。其实看源码分析,如果调用decodeStream方法,其实只要 inPurgeable
为true就够了,inInputShareable是默认为true的,不过别的方法就需要双双为ture,稍后源码分析详述此处。大家只要如上调用就可以让bitmap在Native上了。具体性能会不会有影响,稍后我会写几个demo验证一下。
如图就是源码中的调用,图为BitmapFactory这个源码中decodeStream方法的具体实现,我们可以看到是调用的Native方法,可能有人会问了如果走了else呢,其实else里面的方法跟进去就会发现,也是做了一些处理后,调用nativeDecodeAsset来生成的bitmap。
说到这里我们必须说一个重要的事情,大家千万别以为去调用Native方法就一定是在Native层占用的内存,例如Bitmap.java中的createBitmap也是调用的JNI方法,但其实又反过来回调的Java中的New来做的生成操作。具体的这个地方,我会专门写一篇文章来讲Bitmap和BitmapFactory的源码,从源码中彻底分析一下为什么就是在Native中生成的。
相关文章推荐
- Android开发Bitmap在Native层与Java层内存的两种生成方式
- Android Training - 高效地显示Bitmap(两种缓存Bitmap的方式)与优化Bitmap的内存使用
- 【Android网络开发の3】XML之PULL方式 解析和生成XML文件
- [原]java开发文档的自动生成方式
- 【Android网络开发の1】XML之DOM方式 解析和生成XML文件 推荐
- 【Android游戏开发之十】(优化处理)详细剖析Android Traceview 效率检视工具!分析程序运行速度!并讲解两种创建SDcard方式!
- eclipse 开发android 项目的时候系统自动生成的R.Java文件在重新生成时候丢失问题
- 在android开发中,经常用到去解析xml文件,常见的解析xml的方式有一下三种:SAX、Pull、Dom解析方式。最近做了一个android版的CSDN阅读器,用到了其中的两种(sax,pull)
- java开发之——遍历文件夹的两种方式
- (转)【Android游戏开发之十】(优化处理)详细剖析Android Traceview 效率检视工具!分析程序运行速度!并讲解两种创建SDcard方式!
- Android 开发入门问题集:启动模拟器、安装卸载apk、项目调试、导入Android sample并重新生成R.java……【更新】
- 【Android游戏开发之十】(优化处理)详细剖析Android Traceview 效率检视工具!分析程序运行速度!并讲解两种创建SDcard方式!
- 【Android游戏开发之十】(优化处理)详细剖析Android Traceview效率检视工具,分析程序运行速度!并讲解两种创建SDcard方式!
- java数据库开发中两种注册oracle驱动的方式
- android获取Bitmap的两种方式
- 【Android游戏开发之十】(优化处理)详细剖析Android Traceview 效率检视工具!分析程序运行速度!并讲解两种创建SDcard方式!
- Android-NDK开发之基础--Android JNI有关Java类命名方式
- 【Android网络开发の2】XML之SAX方式 解析和生成XML文件
- Android 生成keystore,两种方式