如果是Native方法,计数器记录为空
堆内存 = 新生代(1) + 老年代(2)
也叫“永久代”,1.8以后将方法区去除了,将方法区移动到直接内存
内存回收主要考虑 堆区 和 方法区 的回收,其他部分会根据线程的产生和消亡
堆中的老年代和方法区(永久代)是绑定的,无论哪一方满了,都会触发双方的GC回收
标记清除算法:标记完后对对象进行回收,使用在 老年代
缺点:
复制算法:将可用对象复制到新的连续空间,删除之前的空间
缺点:
标记整理算法:前期使用标记清除算法,后续使用整理算法,使对象排列称联系空间,使用在 老年代
分代收集算法:对数据进行分代,每一代执行不同的回收算法
年轻代分为eden、s0、s1区,分别为8:1:1,年轻代和老年代为1:2
在内存泄露问题处理上,使用最多的是弱引用,许多源码、框架都是用
eg:
所有的引用都是继承自Reference,以下以WeakReference为例:
public class WeakReference<T> extends Reference<T> {
/**
* Creates a new weak reference that refers to the given object. The new
* reference is not registered with any queue.
*
* @param referent object the new weak reference will refer to
*/
public WeakReference(T referent) {
super(referent);
}
/**
* Creates a new weak reference that refers to the given object and is
* registered with the given queue.
*
* @param referent object the new weak reference will refer to
* @param q the queue with which the reference is to be registered,
* or <tt>null</tt> if registration is not required
*/
public WeakReference(T referent, ReferenceQueue<? super T> q) {
super(referent, q);
}
}
其中存在两种构造方法,区别在于是否传入引用队列,如果不传入引用队列,说明只存在一种引用,不需要引用队列成链存储
public abstract class Reference<T> {
private static boolean disableIntrinsic = false;
private static boolean slowPathEnabled = false;
//引用的对象,由垃圾回收器控制其引用
volatile T referent; /* Treated specially by GC */
final ReferenceQueue<? super T> queue;
Reference queueNext;
Reference<?> pendingNext;
public T get() {
return getReferent();
}
@FastNative
private final native T getReferent();
public void clear() {
clearReferent();
}
@FastNative
native void clearReferent();
public boolean isEnqueued() {
// Contrary to what the documentation says, this method returns false
// after this reference object has been removed from its queue
// (b/267823). ReferenceQueue.isEnqueued preserves this historically
// incorrect behavior.
return queue != null && queue.isEnqueued(this);
}
public boolean enqueue() {
return queue != null && queue.enqueue(this);
}
/* -- Constructors -- */
Reference(T referent) {
this(referent, null);
}
Reference(T referent, ReferenceQueue<? super T> queue) {
this.referent = referent;
this.queue = queue;
}
}
抽象类很简短,可以看出一个关键点,Reference是一个节点,保存next的引用,方法调用都是使用ReferenceQueue方法,直接进入:
private Reference<? extends T> head = null;
private Reference<? extends T> tail = null;
boolean enqueue(Reference<? extends T> reference) {
synchronized (lock) {
if (enqueueLocked(reference)) {
lock.notifyAll();
return true;
}
return false;
}
}
private boolean enqueueLocked(Reference<? extends T> r) {
...
if (r instanceof Cleaner) {
Cleaner cl = (sun.misc.Cleaner) r;
cl.clean();
r.queueNext = sQueueNextUnenqueued;
return true;
}
if (tail == null) {
head = r;
} else {
tail.queueNext = r;
}
tail = r;
tail.queueNext = r;
return true;
}
入队方法中,
SoftReference
>public class SoftReference<T> extends Reference<T> {
//时间戳,由gc更新
static private long clock;
private long timestamp;
public SoftReference(T referent) {
super(referent);
this.timestamp = clock;
}
/**
* Creates a new soft reference that refers to the given object and is
* registered with the given queue.
*
* @param referent object the new soft reference will refer to
* @param q the queue with which the reference is to be registered,
* or <tt>null</tt> if registration is not required
*
*/
public SoftReference(T referent, ReferenceQueue<? super T> q) {
super(referent, q);
this.timestamp = clock;
}
public T get() {
T o = super.get();
if (o != null && this.timestamp != clock)
this.timestamp = clock;
return o;
}
}
由gc管理时间戳
回收条件为:clock - timestamp <= free_heap * ms_per_mb
PhantomReference
public class PhantomReference<T> extends Reference<T> {
public T get() {
return null;
}
public PhantomReference(T referent, ReferenceQueue<? super T> q) {
super(referent, q);
}
}
虚引用的get方法返回null,不做gc保留
虚引用通过构造方法可以查看是 持有对象引用 的
总结:所有引用都是继承自Reference基类的,该类是一个链表节点,ReferenceQueue通过这点形成单链表,称之为队列,进行引用管理,所有引用都可以通过Reference的isEnqueue方法判断引用是否存在。
java堆中创建对象时,如果java类定义了finalize方法,就会新建一个FinalizerReference类,指向这个新建的对象
Android studio自带内存、cpu、网络的变化,可以根据内存变化做具体分析
框架集成,自动检测内存泄漏,生成app,提供内存泄漏栈堆情况
原理:绑定生命周期,对Activity和Fragment来说,在onDestory时将对象放入弱引用队列进行存储,触发gc后,如果还存在,则发生内存泄漏
一款比较老的工具,ThreadPolicy可以检测主线程是否网络访问,是否读写。VMPolicy检测内存,Activity,Fragment是否泄漏,资源是否正确关闭
自动装箱就是将基础数据类型转化为对应的复杂类型,在HashMap的增删改查中充满了自动装箱问题,所以尽量避免这中问题,如将HashMap替换为SparseArray和ArrayMap
在App可用内存过低时主动释放内存
在App退到后台内存紧张即将被Kill掉时选择重写Application中 onTrimMemory/onLowMemory 方法去释放掉图片缓存、静态缓存来自保。
其他场景优化
常规监测
Probe线上监测工具
LeakInspector
ResourceCanary
##最后
小编在网上收集了一些Android 开发相关的学习文档、面试题、Android 核心笔记等等文档,希望能帮助到大家学习提升,如有需要参考的可以直接
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- huatuo0.com 版权所有 湘ICP备2023021991号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务