林玥彤优秀作者
原创内容 来源:小居数码网 时间:2024-07-29 11:15:01 阅读() 收藏:36 分享:54 爆
导读:您正在阅读的是关于【数码知识】的问题,本文由科普作家协会,生活小能手,著名生活达人等整理监督编写。本文有3074个文字,大小约为12KB,预计阅读时间8分钟。
Java虚拟机Java内存模型
线程计数器中如果正在执行java方法,计数器记录的是当前指令的地址,
如果是Native方法,计数器记录为空
堆内存 = 新生代(1) + 老年代(2)
也叫“永久代”,1.8以后将方法区去除了,将方法区移动到直接内存
内存回收主要考虑 堆区 和 方法区 的回收,其他部分会根据线程的产生和消亡
堆中的老年代和方法区(永久代)是绑定的,无论哪一方满了,都会触发双方的GC回收
年轻代分为eden、s0、s1区,分别为8:1:1,年轻代和老年代为1:2
Minor GC : 清理年轻代Major GC : 清理老年代Full GC : 清理整个堆空间,包括年轻代和永久代
在内存泄露问题处理上,使用最多的是弱引用,许多源码、框架都是用
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/26647823). 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
上面就是小居数码小编今天给大家介绍的关于(Android内存优化)的全部内容,希望可以帮助到你,想了解更多关于数码知识的问题,欢迎关注我们,并收藏,转发,分享。
94%的朋友还想知道的:
(350)个朋友认为回复得到帮助。
部分文章信息来源于以及网友投稿,转载请说明出处。
本文标题:android内存性能优化(Android内存优化):http://sjzlt.cn/shuma/152512.html