Java垃圾回收机制解析
2016-07-25 12:30
295 查看
Java垃圾回收机制
一.垃圾回收区:
Java运行时内存区有Java堆,方法区,程序计数器,虚拟机栈,本地方法栈这五个地方,其中程序计数器,虚拟机栈和本地方法栈这三个地方随线程而生,随线程而灭,所以不需要考虑垃圾回收,而Java堆和方法区会伴随着整个JVM的生命周期,所以有必要及时清理掉没有的垃圾。
二.垃圾回收算法:(针对Java堆)
1.Java的垃圾回收算法使用的是可达性分析算法,而不是普通的引用计数算法。
2.引用计数算法原理是:每一个对象都有一个计数器,当一个对象有其他地方引用到它时,它的计数器就加一,当用来 引用它的地方不再指向它时就减一,当对象的计数器为0时,就会被系统回收。引用计数算法简单易懂,然而却有弊端, 比如当对象A指向对象B,同时对象B也指向A,此外没有其他地方引用到这两个对象,理论上A,和B应该算是无用 的对象,应该被回收,然而他们的计数器却都不为0,不能被回收,这就是引用计数算法的弊端,所以Java不使用该垃 圾回收算法。
3.可达性分析算法原理是:图论算法,JVM会选择好gc root作为根结点,然后顺着gc root向下搜索,所以连接到gc root 的对象都是有用对象,不会被回收。而关联不上gc root的对象就会被判定为可回收的对象(注意,这时候会不会马上回 收掉这些对象,会在进一步验证)。具体如下图:
4.一个对象的finalize()方法只会被执行1次。且JVM不会保证对象的finalize()方法会被执行完成(正如Effective Java 里说的),因为如果finalize()方法里有很耗时的操作,那么垃圾回收会执行并且耽误很久,如果是死循环的话会导致 这个虚拟机崩溃,所以不用在finalize()方 法做重要的事情。
三.方法区的垃圾回收:
1.方法区主要回收的是无用的常量和类。
2.常量的回收跟Java堆差不多。
3.类的回收(即类的卸载):
类在加载的时候会把类信息存放在方法区。而方法区也是有垃圾回收机制的,当一个类被回收时就是一个类的卸载 了。一个类在回收很严格,只有当一个类被评定为无用的类时才会被回收,只有同时满足一下3个条件才能算是无 用的类。(要注意,一个被被评定为无用不一定就会马上被回收)
1.该类的所以实例对象都被回收了,即Java堆里不存在该类的实例。
2.加载该类的ClassLoader已经被回收。
3.该类对应的java.lang.Class对象没有在如何地方被引用,无法在任何地方通过反射访问该类的方法。
四.引用:(从强到弱)
1.强引用:
1.创建方式:即Object obj =new Object()这样new出来的对象。
2.特点:主要能关联上gc root,GC永远不会回收该对象。
2.软引用:
1.创建方式:SoftReference<T> sr=newSoftReference<T>(new T());
2.特点:在系统将要OOM时,会把软引用对象列入回收范围进行二次回收。
3.弱引用:
1.创建方式:WeakReference<T> wr = newWeakReference<T>(new T());
2.特点:当垃圾回收器工作时就会回收其对象。
4.虚引用:
1.创建方式:PhantomReference<T> pr =new PhantomReference<T>(new T() , queue);
2.特点:在任何时候都会被回收,且使用pf.get( )返回的都是null。
一.垃圾回收区:
Java运行时内存区有Java堆,方法区,程序计数器,虚拟机栈,本地方法栈这五个地方,其中程序计数器,虚拟机栈和本地方法栈这三个地方随线程而生,随线程而灭,所以不需要考虑垃圾回收,而Java堆和方法区会伴随着整个JVM的生命周期,所以有必要及时清理掉没有的垃圾。
二.垃圾回收算法:(针对Java堆)
1.Java的垃圾回收算法使用的是可达性分析算法,而不是普通的引用计数算法。
2.引用计数算法原理是:每一个对象都有一个计数器,当一个对象有其他地方引用到它时,它的计数器就加一,当用来 引用它的地方不再指向它时就减一,当对象的计数器为0时,就会被系统回收。引用计数算法简单易懂,然而却有弊端, 比如当对象A指向对象B,同时对象B也指向A,此外没有其他地方引用到这两个对象,理论上A,和B应该算是无用 的对象,应该被回收,然而他们的计数器却都不为0,不能被回收,这就是引用计数算法的弊端,所以Java不使用该垃 圾回收算法。
3.可达性分析算法原理是:图论算法,JVM会选择好gc root作为根结点,然后顺着gc root向下搜索,所以连接到gc root 的对象都是有用对象,不会被回收。而关联不上gc root的对象就会被判定为可回收的对象(注意,这时候会不会马上回 收掉这些对象,会在进一步验证)。具体如下图:
4.一个对象的finalize()方法只会被执行1次。且JVM不会保证对象的finalize()方法会被执行完成(正如Effective Java 里说的),因为如果finalize()方法里有很耗时的操作,那么垃圾回收会执行并且耽误很久,如果是死循环的话会导致 这个虚拟机崩溃,所以不用在finalize()方 法做重要的事情。
三.方法区的垃圾回收:
1.方法区主要回收的是无用的常量和类。
2.常量的回收跟Java堆差不多。
3.类的回收(即类的卸载):
类在加载的时候会把类信息存放在方法区。而方法区也是有垃圾回收机制的,当一个类被回收时就是一个类的卸载 了。一个类在回收很严格,只有当一个类被评定为无用的类时才会被回收,只有同时满足一下3个条件才能算是无 用的类。(要注意,一个被被评定为无用不一定就会马上被回收)
1.该类的所以实例对象都被回收了,即Java堆里不存在该类的实例。
2.加载该类的ClassLoader已经被回收。
3.该类对应的java.lang.Class对象没有在如何地方被引用,无法在任何地方通过反射访问该类的方法。
四.引用:(从强到弱)
1.强引用:
1.创建方式:即Object obj =new Object()这样new出来的对象。
2.特点:主要能关联上gc root,GC永远不会回收该对象。
2.软引用:
1.创建方式:SoftReference<T> sr=newSoftReference<T>(new T());
2.特点:在系统将要OOM时,会把软引用对象列入回收范围进行二次回收。
3.弱引用:
1.创建方式:WeakReference<T> wr = newWeakReference<T>(new T());
2.特点:当垃圾回收器工作时就会回收其对象。
4.虚引用:
1.创建方式:PhantomReference<T> pr =new PhantomReference<T>(new T() , queue);
2.特点:在任何时候都会被回收,且使用pf.get( )返回的都是null。
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树