android内存机制

深入理解Android内存回收机制及优化建议
android内存回收


Since it seems a lot of misinformation is being spread in this ticket, I wanted to try and address a few things that might help people before they are led down the wrong path.

First, you must understand a few things about bitmaps and the garbage collector. A bitmap (as of 2.x and earlier), has memory in both the Dalvik and native heap (with the majority of it stored on the native side). The garbage collector is only capable of freeing memory in the Dalvik heap. Native memory for each bitmap is freed using a finalizer.

The exact steps in dalvik to collect a bitmap is as follows:

1) A bitmap becomes eligible for garbage collection
2) The GC eventually runs and sees that the object requires finalization
3) The bitmap is placed onto the finalizer queue
4) The finalizer eventually runs and native memory is freed (at this point, most of the memory you assigned to the bitmap is freed)
5) The GC eventually runs again and the bitmap is removed from the Dalvik heap. This "remainder" object is relatively small when compared to the previously in-use native memory

There are a few things you should understand about finalizers. The following is some data I extracted from http://publib.boulder.ibm.com/infocenter/javasdk/v5r0/index.jsp?topic=%2Fcom.ibm.java.doc.diagnostics.50%2Fhtml%2Fmm_gc_coexist.html

Finalizers:
Are not run in any particular sequence
Are not run at any particular time
Are not guaranteed to run at all
Will run asynchronously to the Garbage Collector

So lets talk about what does happen when you try to allocate a bitmap and there is no memory available:

1) A bitmap or large chunk of memory tries to be allocated
2) The JVM realizes there isn't enough memory available
3) The JVM kicks off a GC to prevent an out of memory error (http://download.oracle.com/javase/1.4.2/docs/api/java/lang/OutOfMemoryError.html)
4) The GC completes and the allocation is attempted again. If it fails, an out of memory error is thrown, Otherwise, you get the memory

So, the key thing to notice in the above steps is that the finalizer queue is NOT run until its empty or even mentioned at all. The main problem everyone is having is that they are stuck waiting for the finalizer thread to allow the release of the native memory bitmaps are using.

To fix this problem, simply be sure to call recycle() on bitmaps when you are done using them. This will free the large portion of native memory they use, and will prevent the problems everyone has been having.


Fast Tips:

1) NEVER call System.gc() yourself. This has been propagated as a fix here, and it doesn't work. Do not do it. If you noticed in my explanation, before getting an OutOfMemoryError, the JVM already runs a garbage collection so there is no reason to do one again (its slowing your program down). Doing one at the end of your activity is just covering up the problem. It may causes the bitmap to be put on the finalizer queue faster, but there is no reason you couldn't have simply called recycle on each bitmap instead.

2) Always call recycle() on bitmaps you don't need anymore. At the very least, in the onDestroy of your activity go through and recycle all the bitmaps you were using. Also, if you want the bitmap instances to be collected from the dalvik heap faster, it doesn't hurt to clear any references to the bitmap.

3) Calling recycle() and then System.gc() still might not remove the bitmap from the Dalvik heap. DO NOT BE CONCERNED about this. recycle() did its job and freed the native memory, it will just take some time to go through the steps I outlined earlier to actually remove the bitmap from the Dalvik heap. This is NOT a big deal because the large chunk of native memory is already free!

4) Always assume there is a bug in the framework last. Dalvik is doing exactly what its supposed to do. It may not be what you expect or what you want, but its how it works.



Finalizer:

  收尾:每个类都有一个特殊的方法finalizer,它不能被直接调用,而被JVM在适当的时候调用,通常用来处理一些清理资源的工作,因此称为收尾机制。



相关链接:
1.How to discover memory usage of my application in Android


2.Android内存情况 ; http://blog.youkuaiyun.com/wangqilin8888/article/details/7737278

3.http://my.oschina.net/kangchunhui/blog/67613

4.http://47.lyywin.com/news1/679.html

5.http://blog.youkuaiyun.com/jianzhengzhouzjz/article/details/7623516

6.http://blog.youkuaiyun.com/shlpyy/article/details/6831104



Android内存机制在不同版本之间有着较大的演变,其中最主要的就是内存管理策略的变化。在早期的Android版本中,内存管理采用的是进程优先级的方式,即根据进程的重要性和消耗的资源量来确定内存使用的权重,但这种方式容易导致内存不足的情况,进而导致应用程序崩溃。 后来,Google在Android 2.0中引入了LowMemoryKiller机制,通过监控系统内存使用情况,当内存不足时自动清理不必要的进程,以释放内存资源。LowMemoryKiller机制的实现是通过kernel的oom-killer机制来实现的,当系统内存不足时,通过oom_adj值来判断哪些进程可以杀掉,以释放内存资源。在Android 2.x中,LowMemoryKiller机制主要依赖于进程oom_adj值的设置,以及进程的重要性和消耗的资源量来判断哪些进程可以被杀掉。 随着Android版本的不断升级,Google也对LowMemoryKiller机制进行了多次优化,主要包括: 1. Android 3.0中引入了memcg机制,通过将进程的内存资源划分为多个cgroup,实现对内存资源的精细化管理。 2. Android 4.0中引入了Lmkd机制,通过对进程的内存资源进行动态调整,以更加精准地释放内存资源。 3. Android 4.4中引入了Zram机制,通过将一部分物理内存作为压缩内存使用,提高内存使用效率。 4. Android 6.0中引入了Doze机制,通过限制应用程序的后台运行,以降低系统内存负载。 总的来说,Android内存管理机制是不断演变和优化的过程,不断追求更加高效和精细化的内存管理方式,以保证系统的稳定性和性能。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值