Java内存回收机制

来源:互联网 发布:淘宝卖假的隐形眼镜 编辑:程序博客网 时间:2024/05/23 19:13

文章转自:http://blog.csdn.net/qq_22854537/article/details/51520944
Java的内存泄漏:如果存在无用的内存没有被回收回来,那就是内存泄漏。
垃圾回收机制:垃圾回收机制主要完成下面两件事情:
1、跟踪并监控每个Java对象,当某个对象处于不可达状态时,回收该对象所占用的内存空间;
2、清理内存分配、回收过程中产生的内存碎片。
JVM的垃圾回收机制采用有向图的方式来管理内存中的对象,采用有向图来管理内存中的对象具有高的精度,但缺点是效率较低。对于内存中的某个对象,只要有引用变量引用它,垃圾回收机制就不会回收它;反之,当一个对象失去引用时,JVM的垃圾回收机制会自动清理它们,并回收它们所占用的内存空间。在有向图中,一个对象如果处于不可达状态,则视为这个对象没有不再被引用,接下来垃圾回收机制就会主动回收它了。有一种情况是:有3个对象在引用,A引用B,B引用C,C引用A,它们都没有失去引用,但只要从有向图的起点不可达它们,垃圾回收机制也会回收它们。

当一个对象在堆内存中运行时,根据它在对应有向图中的状态,可以把它所处的状态分成3种:可达、可恢复和不可达状态。
为了更好的管理引用,从JDK1.2开始,Java在java.lang.ref包提供了3个类:SoftReference、PhantonReference、WeakReference。它们分别代表了系统对对象的3种引用方式:软引用、虚引用和弱引用。

归纳起来,Java语言对对象的引用有如下4中:软引用、强引用、虚引用、软引用。

强引用:
这是Java对象最常见的引用方式,程序创建一个对象,并把这个对象赋给一个引用变量,这个引用变量就是引用。当一个对象被一个或多个强引用变量引用时,它处于可达状态,它不可能被垃圾回收机制回收。由于JVM肯定不会回收强引用所引用的对象,因此强引用是造成Java内存泄漏的主要原因之一。
软引用:
软引用需要SoftReference类来实现,当一个对象只有软引用时,它有可能被垃圾回收机制回收。对于只有软引用的对象而言,当系统内存足够时,它不会被系统回收,程序也可以使用该对象;当系统空间不足时,系统会回收它。
弱引用:
弱引用与软引用有些相似,区别在于弱引用所引用的对象生存周期更短。对于只有弱引用的对象,当系统垃圾回收机制回收时,不管内存是否足够,总会回收该对象的内存空间。当然,并不是说当一个对象只有弱引用时就会立刻被回收,正如那些失去引用的对象,必须等到垃圾回收机制运行时才会被回收。
虚引用:
软引用和弱引用可以单独使用,但是虚引用不能,单独使用没有太大的意义。虚引用的主要作用就是跟踪对象被垃圾回收的状态,程序可以通过检查虚引用关联的引用队列中是否已经包含指定的虚引用,从而了解虚引用所引用对象是否即将被回收。虚引用通过WeakReference实现,它类似于完全没有引用,必须与引用队列(ReferenceQueue)联合使用。
垃圾回收的基本算法:串行回收和并行回收;并发执行和应用程序停止;压缩和不压缩和复制。
堆内存的分代回收:分代回收的一个依据就是对象的生存时间长短,把堆内存分成3代:young代、old代和permanent代。
当young代内存紧张的时候,垃圾回收机制就会回收young代的内存空间,垃圾回收机制会采取较高的频率对young代进行扫描和回收(次要回收)。young代没有回收的对象会变成old代对象。当Old代内存要用完时,垃圾回收机制就会进行全回收,也就是对young和old代都回收(主回收)。
通常来说,young代的内存会先被回收,而且采用专门的算法(复制算法)来回收young代的内存;对Old代的内存回收频率要低得多,因此也会使用专门的回收算法。如果需要进行内存压缩,每个代都要独立的进行压缩。

内存管理的小技巧:
1、尽量使用直接量
例如,程序需要“hello”字符串,应用一下代码:String str=“hello”;
好处是它会被JVM的缓存池缓存,而且相对于String str=new String(“hello”),new出来的字符串对象底层还包含一个h,e,l,l,o的char[]对象数组。
2、使用StringBuilder和StringBuffer进行字符串连接
3、尽早释放无用对象的引用
4、尽少使用静态变量
5、避免在经常调用的方法、循环中创建Java对象
6、缓存经常使用的对象
7、尽量不要使用finalize方法
8、考虑使用SoftReference

原创粉丝点击