一、虚引用

虚引用在实际的开发过程中应用的比较少。虚引用有一下几个特点:
(1)虚引用在垃圾回收器回收的时候被回收
(2)虚引用在通过get()方法获取的对象都为空,所以也被称为幽灵引用

(3)虚引用不会决定一个对象的生命周期,如果一个对象持有一个虚引用,那么它就和没有任何引用是一样的。

所以,根据上述的三个特点可以知道,虚引用主要用来监听所关联的对象什么时候被回收。操作如下:
@Test public void testPhantomReference() throws InterruptedException {
//队列,当对象被垃圾回收器回收的时候会被放到这个队列里 ReferenceQueue<Object> referenceQueuee=new
ReferenceQueue<>(); //被关联的对象 Object phantomObject=new Object(); //创建一个虚引用
PhantomReference phantomReference=new
PhantomReference(phantomObject,referenceQueuee); //将对象置空,之后等待被垃圾回收器回收
phantomObject=null; System.out.println("phantomObject:"+phantomObject);//null
//此时垃圾回收器还没回收置空的对象,所以队列的返回值是null
System.out.println("referenceQueuee:"+referenceQueuee.poll());
//isEnqueued:true表示已经被回收,false表示还未被回收。此时返回值是false
System.out.println("isEnQueued:"+phantomReference.isEnqueued()); System.gc();
Thread.sleep(2000);
System.out.println("-----------------------------------------");
//注意:isEnqueued一定要在队列poll之前执行
System.out.println("isEnQueued:"+phantomReference.isEnqueued());
System.out.println("referenceQueuee:"+referenceQueuee.poll()); }
输出如下:
 
phantomObject:null referenceQueuee:null isEnQueued:false
----------------------------------------- isEnQueued:true
referenceQueuee:java.lang.ref.PhantomReference@f2a0b8e
二、弱引用

弱引用和虚引用有一定的区别。

(1)虚引用需要和ReferenceQueue配合使用,而弱引用则不需要。

(2)虚引用通过get()获取的对象为空,而弱引用则获取的是对象

所以使用弱引用可以很好的避免内存泄漏的问题。如果你想随时使用某个生命周期短的对象,又不影响它的回收,建议使用弱引用
@Test public void testWeakReference() throws InterruptedException {
ReferenceQueue<Object> referenceQueuee=new ReferenceQueue<>(); Object
weakObject=new Object(); //弱引用,可以关联队列,也可以不管理。构造器有两种 WeakReference
weakReference=new WeakReference(weakObject,referenceQueuee);
System.out.println("WeakReference:"+weakReference.get());
System.out.println("isEnqueued:"+weakReference.isEnqueued());
System.out.println("referenceQueuee:"+referenceQueuee.poll()); weakObject=null;
System.gc(); Thread.sleep(2000);
System.out.println("--------------------------------------");
System.out.println("WeakReference:"+weakReference.get());
System.out.println("isEnqueued:"+weakReference.isEnqueued());
System.out.println("referenceQueuee:"+referenceQueuee.poll()); }
输出如下:
WeakReference:java.lang.Object@593634ad isEnqueued:false referenceQueuee:null
-------------------------------------- WeakReference:null isEnqueued:true
referenceQueuee:java.lang.ref.WeakReference@20fa23c1
三、内存分析工具

Android Studio有很好的分析内存及CPU分析工具Profile



和应用关联之后,会有如下的图展示



我们主要分析内存,所以点击上图红色框的部分,会变成如下的表现形式



关于Profile的使用,可以百度,可以对应用做出各种情况的分析。这里我说的是另外一种工具,可以和Profile配合使用,叫做MemoryAnalyzer。
百度搜索,自行下载~

如何配合使用呢。

1.导出Profile某个时间段的内存数据

点击红色框的按钮,会出现黑色框的内容。在黑色框内容中,右键点击Export,保存。



2.修改导入的数据文件格式

进入到SDK路径———>platform-tools目录中,找到hprof-conv.exe文件。然后进入到cmd模式,或者加入到环境变量中。
#src_1.hprof:表示刚刚保存的内存数据文件 #dist_1.hprof:表示转换的内存数据文件 hprof-conv -z src_1.hprof
dist_1.hprof
3.使用MemoryAnalyzer打开文件

点击File-->Open Heap Dump找到刚刚转换的文件



打开后基本如下,我们可以在下图的红色框部分寻找自己需要的数据,可以自己点击尝试阅读,或者百度一下相关的教程吧。



本篇文章到此结束,之后还会有第二篇内存优化的文章。欢迎提问,欢迎纠错!

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:637538335
关注微信