正如前面所说,静态变量的生命周期等同于应用的生命周期,此处传入的Context参数就是祸胎。如不雅传递进去的是Activity或者Fragment,因为单例一向持有它们的引用,即便Activity或者Fragment烧毁了,也不会回收其内存。特别是一些宏大年夜的Activity异常轻易导致OOM。
Java可以作为GC ROOT的对象有:虚拟机栈中引用的对象(本地变量表),办法区中静态属性引用的对象,办法区中常量引用的对象,本处所法栈中引用的对象(Native对象)
2. 标记清除法:大年夜根节点集合进行扫描,标记存活的对象,然后再扫描全部空间,对未标记的对象进行收受接收。在存活对象较多的情况下,效力很高,然则会造成内存碎片。
3. 标记整顿算法:同标记清除法,只不过在收受接收对象时,对存活的对象进行移动。固然解决了内存碎片的问题然则增长了内存的开销。
4. 复制算法:此办法为克服句柄的开销和解决堆碎片。把堆分为一个对象面和多个余暇面。把存活的对象copy到余暇面,重要余暇面就变成了对象面,本来的对象面就变成了余暇面。如许增长了内存的开销,且在交换过程中法度榜样会暂停履行。
5. 分代算法:分代垃圾收受接收策略,是基于:不合的对象的生命周期是不一样的。是以,不合生命周期的对象可以采取不合的收受接收算法,以便进步收受吸见效力。
年青代:
1. 所有新生成的对象起首都是存放在年青代。年青代的目标就是尽可能快速的收集掉落那些生命周期短的对象。
2. 新生代内存按照8:1:1的比例分为一个eden区和两个survivor(survivor0,survivor1)区。一个Eden区,两个 Survivor区(一般而言)。大年夜部分对象在Eden区中生成。收受接收时先将eden区存活对象复制到一个survivor0区,然后清空eden区,当这个survivor0区也存放满了时,则将eden区和survivor0区存活对象复制到另一个survivor1区,然后清空eden和这个survivor0区,此时survivor0区是空的,然后将survivor0区和survivor1区交换,即保持survivor1区为空, 如斯来去。
3. 当survivor1区不足以存放 eden和survivor0的存活对象时,就将存活对象直接存放到老年代。若是老年代也满了就会触发一次Full GC,也就是新生代、老年代都进行收受接收
4. 新生代产生的GC也叫做Minor GC,MinorGC产生频率比较高(不必定等Eden区满了才触发)
年迈代:

1. 在年青代中经历了N次垃圾收受接收后仍然存活的对象,就会被放到年迈代中。是以,可以认为年迈代中存放的都是一些生命周期较长的对象。
2. 内存比新生代也大年夜很多(大年夜概比例是1:2),当老年代内存满时触发Major GC即Full GC,Full GC产生频率比较低,老年代对象存活时光比较长,存活率标记高。
持久代:
用于存放静态文件,如Java类、办法等。持久代对垃圾收受接收没有明显影响,然则有些应用可能动态生成或者调用一些class,例如Hibernate 等,在这种时刻须要设置一个比较大年夜的持久代空间来存放这些运行过程中新增的类。
Android常见的内存泄漏汇总
集合类泄漏
先看一段代码
- List<Object> objectList = new ArrayList<>();
- for (int i = 0; i < 10; i++) {
- Object o = new Object();
- objectList.add(o);
- o = null;
- }
膳绫擎的实例,固然在轮回中把引用o释放了,然则它被添加到了objectList中,所以objectList也持有对象的引用,此时该对象是无法被GC的。是以对象如不雅添加到集合中,还必须大年夜中删除,最简单的办法
这会导致一系列问题,如不雅你的app过程设计上是长驻内存的,那即使app切到后台,这部分内存也不会被释放。按照如今手机app内存治理机制,占内存较大年夜的后台过程将优先收受接收,意味着如不雅此app做过过程互保保活,那会造成app在后台频沉重启。就会出现一夜时光手机被消费空了电量、流量,如许只会被用户弃用。
- //释放objectList
- objectList.clear();
推荐阅读
此次的成功融资让金山云的用户也跟着受益,因为金山云的主流产品将周全降价,个中CDN、云数据库Redis新价动人,降幅最大年夜可达到50%、60%;云办事器价格最大年夜降幅跨越30%;对象存储产品>>>详细阅读
本文标题:Android面试被问到内存泄漏了杂整?
地址:http://www.17bianji.com/lsqh/39898.html
1/2 1

网友点评
精彩导读
科技快报
品牌展示