您的位置:首页 > 编程语言 > Java开发

内存优化-java四种引用,让你能更好的构建你的项目

2017-06-12 03:00 387 查看

前言:

Activity和fragment都有生命周期,那对于我们的java对象而言同样是有生命周期的,比较笼统的说,那就是当他被创建的时候一直到GC回收终止,这样一个对象的生命周期就走完了。而java为我们提供了4种引用类型,分别是
1.强引用-StrongReference
2.弱引用-WeakReference
3.软引用-SoftReference
4.虚引用-PhantomReference
这4中引用类型与我们的GC有着密切的关系,而我们项目运行的时候,导致项目的运行内存一直增加,这就是我们所创建的对象一直无法被回收而导致内存泄漏(当然,在项目中做的缓存除外)。所以熟练的运用java为我们提供的4种引用,能在很多方面避免我们因为代码时不经意造成的内存泄漏。

强引用:

这是我们用到最普遍的一种引用方式,就比如Object obc = new Object(); 这就是一个强引用,如果当GC Roots可达时,这个obc就不会被回收(哪怕程序发生OOM),而我们的内存泄漏基本也是由于强引用造成的,而大多数情况下都是因为java的机制,非静态内部类匿名内部类持有外部类引用,所以造成了内存泄漏,我在优化自己项目的时候就排查到很多这种情况,当然还有另外的情况,等下说项目例子的时候会说到。

弱引用:

生命周期更短,这是相对于软引用而言,因为它在系统进行GC操作的时候,无论内存是否充足,它都会被GC回收。它的声明方式是WeakReference<Activity> weakReference = new WeakReference<Activity>(activity); 而要拿到这个activity对象,只要通过weakReference.get();就可以获取到了。当然它还可以与java为我们提供的ReferenceQueue一起使用,当弱引用被内存回收的时候,就会添加到ReferenceQueue队列中,我们就可以知道它是否已经被回收了,同时也能拿到这个弱引用对其操作,不过这个ReferenceQueue在项目中基本没用到过。它具体运用的地方,可以看下我这篇博客,其中有张图是把handler给声明为弱引用,这样就避免了内存泄漏的情况。
weakReference使用实例

软引用:

生命周期相对于弱引用而言更长点,它被GC回收的时机是当内存不足的时候,也就是说GC触发并不一定会回收软引用,所以它运用到的地方很多都是一些缓存操作,例如可以把要一些不重要的缓存定义为弱引用,这样当内存不足的时候触发GC操作,这些缓存就可以回收了,也就减少了OOM的可能性。当然它也可以与ReferenceQueue一起使用,于弱引用类似。它的声明方式是SoftReference<Activity>
softReference = new SoftReference<Activity>(activity);当然要获取到这个activity的引用也是通过softReference.get()获取的。

虚引用:

这如同它名字一样,它不影响对象的声明周期,随时会被回收,这个至今还没有用到过,不过要是用它必须要与ReferenceQueue一起使用,可以通过ReferenceQueue来知道虚引用是否被回收了,再后续对其进行操作。

前面说强引用的时候还说过一种情况,就是当不是使用内部类的时候也可能会造成内存泄漏,有种情况就是当一个变量是静态的时候,同时又持有你这个对象的引用,这样也会造成内存泄漏。例如单例模式等,所以这时候你就可以使用弱引用来解决这种问题。当然还有其他的情况下,这个就要根据自己的项目来了,在我优化自己项目的时候,排查到一个内存泄漏的情况,就是在自定义Activity的基类中有一个Activity的Queue,通过这个Queue可以方便我们应用退出时能及时finish掉我们所有的Activity,由于以前的同事没有意识到这样会造成内存泄漏,这个Queue一直持有put到其中的activity的引用。这种情况下,我们就可以通过弱引用来解决这种问题了,避免了项目中的内存泄漏。

通过了解java的4中引用,希望能帮助你更好的构建你的项目,避免一些不注意的情况下造成的内存泄漏。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: