|
|
1.Bitmap
1.1 Bitmap内存
Android管理Bitmap内存使用的演变进程:
- 在Android 2.2 (API level 8)以及之前,当垃圾回收发生时,应用的线程是会被暂停的,这会导致一个延迟滞后,并降低系统效率。 从Android 2.3开始,添加了并发垃圾回收的机制, 这意味着在一个Bitmap不再被引用之后,它所占用的内存会被立即回收。
- 在Android 2.3.3 (API level 10)以及之前, 一个Bitmap的像素级数据(pixel data)是存放在Native内存空间中的。 这些数据与Bitmap本身是隔离的,Bitmap本身被存放在Dalvik堆中。我们无法预测在Native内存中的像素级数据何时会被释放,这意味着程序容易超过它的内存限制并且崩溃。 自Android 3.0 (API Level 11)开始, 像素级数据则是与Bitmap本身一起存放在Dalvik堆中。
- 从Android 3.0 (API Level 11)开始,引进了BitmapFactory.Options.inBitmap字段。 如果使用了这个设置字段,decode方法会在加载Bitmap数据的时候去重用已经存在的Bitmap。这意味着Bitmap的内存是被重新利用的,这样可以提升性能,并且减少了内存的分配与回收。然而,使用inBitmap有一些限制,特别是在Android 4.4 (API level 19)之前,只有同等大小的位图才可以被重用。详情请查看inBitmap文档。
2.Ashmem(Ashmem匿名共享内存)
2.1场景来源
开源库Fresco,采用了Ashmem匿名共享内存机制, 来解决图片加载中的OOM问题。也就是不占用Java内存。那么了Ashmem匿名共享内存是什么,如何达到不占用Java内存的呢
2.2 Android 内存区域
- 1.Java Heap(Dalvik Heap),JVM管理GC
- 2.Native Heap,这部分是C++内存区域,它不受限于APP的最大可用内存限制,而只是受限于设备的物理可用内存限制。它的缺点在于没有自动回收机制,只能通过C++语法来释放申请的内存
- 3.Ashmem(Ashmem匿名共享内存):这部分内存类似于Native内存区,但是它是受Android系统底层管理的,当Android系统内存不足时,会回收Ashmem区域中状态是 unpin 的对象内存块,如果不希望对象被回收,可以通过 pin 来保护一个对象
2.3 为什么Fresco 后来废弃使用Ashmem?什么是inBitmap?
如果一个 unpinned 的bitmap在之后又要被使用,系统会运行时又将它重新decode,但是这个decode操作是发生在UI线程中的有可能会造成掉帧现象,因此改做法已经被Google废弃掉,转为鼓励使用 inBitmap 来告知bitmap解码器去尝试使用已经存在的内存区域,新解码的bitmap会尝试去使用之前那张bitmap在heap中所占据的pixel data内存区域,而不是去问内存重新申请一块区域来存放bitmap。
3.mmap内存映射是什么?
共享内存允许两个或多个进程共享一给定的存储区,因为数据不需要来回复制,所以是最快的一种进程间通信机制。共享内存可以通过mmap()映射普通文件
常规磁盘读写操作,进程I/O时,会开辟一个缓冲区域,然后在对文件进行读写。而mmap越过缓冲区域直接进行I/O。所以mmap效率很高。与此同时,其自动回写机制,避免了终止进程带来的I/O缺失。常用语日志读写。