系统对对象的引用方式
对垃圾回收机制来说,判断一个对象是否可回收的标准就在于该对象是否被引用,因此饮用也是JVM进行内存管理的一个重要概念。为了更好的管理对象的引用,从JDK1.2开始,Java在java.lang.ref包下提供了三个类:SoftReference、PhantomReference和WeakReference,它们分别代表了系统对对象的三种引用方式:软引用、虚引用和弱引用。归纳起来,Java语言对对象的引用有以下四种:
>>强引用
>>软引用
>>弱引用
>>虚引用
下面分别介绍:
这是Java程序中最常见的引用方式,程序创建一个对象,并把这个对象赋给一个引用变量,这个引用变量就是强引用。
强引用是Java编程中广泛使用的引用类型,被强引用所引用的Java对象绝不会被垃圾回收机制回收,即使系统内存非常紧张;即使有些Java对象以后永远不会被用到,JVM也不会回收被强引用所引用的对象。
由于JVM肯定不会回收被强引用所引用的Java对象,因此强引用是造成Java内存泄露的主要原因。
软引用需要通过SoftReference类来实现,当一个对象只有软引用时,它有可能被垃圾回收机制回收,对于只有软引用的对象而言,当系统内存足够时,它不会被系统回收,程序也可使用该对象;当系统内存空间不足时,系统肯定回收它。这是它相对与强引用最大的不同,这有利于避免系统内存不足引起的异常。
例如,我们要用数组存储数目较多的对象,比如1000个,如果采用强引用的话可以保证每个对象都不丢失,但是容易造成内存紧张,但是如果用软引用:
<span style="background-color: rgb(255, 102, 102);">SoftReference<Person>[] people=new SoftReference[1000];</span>
当内存充足时,与强引用没有什么不同,当内存紧张时,则可以回收部分被软引用所引用的对象
弱引用与软引用有点相似,区别在于弱引用所引用的对象的生存期更短。弱引用通过WeakReference类实现,弱引用和软引用很像,但弱引用的引用级别更低。对于只有弱引用的对象而言,当系统垃圾回收机制运行时,不管系统内存是否足够,总会回收该对象所占的内存。当然,并不是说当一个对象只有弱引用时,它就会立刻被回收——必须等到系统垃圾回收机制运行时才会被回收。
Java程序示例:
package 弱引用; import java.lang.ref.WeakReference; public class WeakReferenceTest { public static void main(String[] args) { //创建一个字符串 String str=new String("你是风儿我是沙"); //创建一个弱引用,引用到“你是风儿我是沙”字符串 WeakReference<String> wr=new WeakReference<String>(str); //切断str到字符串对象的强引用 str=null; //取出弱引用所引用的对象 System.out.println("在垃圾回收机制启动前,弱引用所引用的对象依然存在:"+wr.get()); //开启垃圾回收机制 System.gc(); System.runFinalization(); //再次取出弱引用所引用的对象 System.out.println("启动垃圾回收机制后,弱引用所引用的对象被回收,所以输出为:"+wr.get()); } }
软引用和弱引用可以单独使用,但虚引用不能单独使用,单独使用虚引用没有太大意义。虚引用的主要作用就是跟踪对象被垃圾回收的状态。
Java的内存泄漏
定义:程序运行过程中会不断地分配内存空间,那些不再使用的内存空间应该及时被回收,从而保证系统可以再次使用这些内存,如果存在无用的内存没有被回收回来,那就是内存泄漏。
注意:如果程序中有一些Java对象,它们处于可达状态,但程序以后永远都不会再访问它们,那么它们所占有的内存空间也不会被回收,这也会造成内存泄漏。