java垃圾回收与安卓内存分析

12 篇文章 0 订阅

首先,我们来说说内存泄漏与内存溢出。我们知道程序运行过程中会产生很多的对象,而有些对象用过之后就不用了。这时候就要对其所占的内存进行释放。如果释放不了,这就造成了内存泄漏。而当多次创建这种对象,这时候内存一直涨超过安卓app可拥有的最大内存就会产生内存溢出。所以,内存溢出和内存泄漏没必然关系。

正常情况导致的内存溢出我们就不说了,我们要研究的是内存泄漏,不管它有没有溢出。追究内存泄漏的根源在于对象没有释放。我们把不应该存在的对象叫垃圾,所以下面要说的是java垃圾回收机制。

垃圾回收,首先我们要判断哪些是垃圾(垃圾标记)。这里有两种算法:
1.引用计数:每一个对象负责维护对象所有引用的计数值。当一个新的引用指向对象时,引用计数器就递增,当去掉一个引用时,引用计数就递减。当引用计数到零时,该对象就将释放占有的资源。这种算法的好处是实时,坏处是不能解决循环引用。
2.根搜索算法:java使用的,这个算法的基本思路就是通过一系列的名为“GC Root”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain)。当然java还有一些优化,让我们可以人为控制垃圾收集器,于是有了软引用、弱引用、虚引用。

其次,我们要来说说垃圾的回收的实现(垃圾清除),这里有很多:
1.直接清除:最简单的,直接把所有被标记的垃圾清除,一般使用单线程工作并停止其他操作。产生大量的不连续的内存碎片,效率也不高。
2.压缩清除:直接清除的优化。先把不是垃圾的移到一端,然后把其余的清空。存活对象太多时效率低下。
3.复制清除:把内存分为两半,每次只用其中一半。每次只用一半,这半用完了就把存活的复制到另一半,把这一半清空。典型的以空间换时间。
4.分代清除(java):把堆栈分为两个或多个域(java为新生代,年老代与永久代),用以存放不同寿命的对象。利用算法得到不同对象的寿命,并可以根据不同域做自适应的清除算法。
5.并行清除:这个一般都是作为结合使用。
好了,我们进入正题:安卓内存分析。分析的目的肯定是找到内存泄漏了,所以我们先要判断是否有内存泄漏。上面说了泄漏和溢出没必然关系,不过通常我们是内存溢出了才想起是否泄漏了。我们知道内存溢出时,每次新建对象都会使内存上升。并且是不能回收的。判断是否可回收就要用到Android Monitor了,我们说的内存分析也就是用它了。怎么用呢,看一张图。
android monitors
1.强制gc回收内存,这样就剩下不可回收和泄漏的。
2.dump内存的.hprof文件,用于分析。hprof文件具体各个参数看这里(必看)
3.追踪内存具体方法分配,主要用于优化。
我们都知道android的四大组件,其中用的最多也最容易产生内存溢出的是activity。当我们怀疑哪个activity发生了内存泄漏,我们进去之前点1,进去之后蓝色的内存会涨。然后出来之后点1.看内存是否下来。没下来就发生了内存泄漏,我们点2并找到那个activity。

当然,我们怀疑那个activity总是有点不靠谱。这时候就需要我们用另一个工具了LeakCanary,这样当一个activity附近发生泄漏(记住在activity的onDestroy之后才会发现泄漏),LeakCanary会使应用停下来。我们就有针对的怀疑哪个activity了。leakCanary具体使用看这里

最后说一下,我为啥在前面说了一大篇的垃圾回收,而后面的内存分析工具使用只是引用别人的东西。因为我们明白了原理之后,才能更好的使用工具。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值