java中的gc垃圾回收机制
来源:互联网 发布:php空间 编辑:程序博客网 时间:2024/05/16 06:41
1、所谓垃圾回收机制:是JVM对堆内存区域的回收
2、怎样确定一个线程是否可以被回收:
方法一:计数法:在内存中用计数器记录该对象被引用的次数,当被引用时就+1,对象释放就-1,当计数器中数为0时说明是该回收的线程了。但是这种方法有漏洞:当A 和B两个对象相互引用形成循环,那么计数器中的数就一直是1,这样就不会被察觉得到。这样就用到了
第二种方法:
方法二:根搜索:就是找这个对象有没有路径可以到达根,如果有则不回收,如果没有那么进行回收。
如下图:对象D访问不到根对象,所以就会被回收
3、在根搜索所得到的回收对象前有一个复活环节:有且仅有一次复活机会,如果不能复活,那么就会永远死去,呵呵。实现他的函数是finalize(),我们要重写一下:以下对象会被认为是root对象:
- 被启动类(bootstrap加载器)加载的类和创建的对象
- jvm运行时方法区类静态变量(static)引用的对象
- jvm运行时方法去常量池引用的对象
- jvm当前运行线程中的虚拟机栈变量表引用的对象
- 本地方法栈中(jni)引用的对象
package deadToLive;/** * Created by Administrator on 2015/11/3 0003. */public class DeadToAlive { private static DeadToAlive deadToAlive; public void finalize() throws Throwable{ try { super.finalize(); DeadToAlive.deadToAlive=this; } catch (Throwable throwable) { throwable.printStackTrace(); } } public static void main(String[] args) throws InterruptedException { DeadToAlive.deadToAlive=new DeadToAlive(); DeadToAlive.deadToAlive=null; System.gc(); Thread.sleep(500); if(deadToAlive!=null) System.out.println("Alive"); else System.out.println("Dead"); DeadToAlive.deadToAlive=null; System.gc(); Thread.sleep(500); if(deadToAlive!=null) System.out.println("Alive"); else System.out.println("Dead"); }}首先标记一次,将其放在F-queue队列中,等待执行finalize()函数,执行后GC进行二次标记,而此时赴会的不会被标记,只有在执行完finalize()后仍然dead的那么就直接进行回收了。
4、垃圾回收的策略:
(1)标记--清除:直接将内存中二次标记的的线程进行消除,这样简便但是会造成碎片的产生,内存的浪费。
(2)标记--复制:将堆分成8:1:1的1个Eden和2个survivor构成新生代。
每次将Eden和Survivor中存活的对象
复制到另一块空闲的Survivor中。这三块区域并不是堆的全部,而是构成了新生代。
从下图可以看到这三块区域如何配合完成GC的,具体的对象空间分配以及晋升请
为什么不是全部呢?如果回收时,空闲的那一小块Survivor不够用了怎么办?这就是
老年代的用处。当不够用时,这些对象将直接通过分配担保机制进入老年代。那么
老年代也使用标记-复制策略吧?当然不行!(老年代是使用标记--整理策略)老年代中的对象可不像新生代中的,
每次回收都会清除掉大部分。如果贸然采用复制的策略,老年代的回收效率可想而知。
(3)标记--整理:将所有Alive下来的线程都整理到一块去,这样解决了(1)的局限性,并且满足老年代的特点。
(1)新生代的GC:
serial:单线程,当他进行回收时,其它工作线程必须暂停
parNew:多线程
parallel scavenge:吞吐量优先
(2)老年代的GC:
serial old:单线程
parallel old:多线程
CMS:是基于标记--清除
6、什么情况下进行GC:
(1)新生代回收:
Minor GC(新生代回收)的触发条件比较简单,Eden空间不足就开始进行Minor GC回收新生代。
(2)老年代回收:(1)老年代空间不足
(2)PermSpace空间不足
(3)统计得到的Minor GC晋升到老年代的平均大小大于老年代的剩余空间
这里注意一点:PermSpace并不等同于方法区,只不过是Hotspot JVM用PermSpace来
实现方法区而已,有些虚拟机没有PermSpace而用其他机制来实现方法区。
7、要回收对象空间分配和晋升:对象优先分到新生代的Eden中
大对象分配到老年代中
新生代中的对象每熬过一次Minor GC就会+1岁,当为15岁时就会进入老年代
资源来源:http://blog.csdn.net/dc_726/article/details/7934101
1 0
- java中的垃圾回收机制GC
- Java中的垃圾回收机制GC
- java中的gc垃圾回收机制
- java中的GC垃圾回收机制分析
- JAVA gc垃圾回收机制
- Java垃圾回收机制----GC
- JAVA 垃圾回收机制GC
- java垃圾回收机制GC
- JAVA gc垃圾回收机制
- JAVA gc垃圾回收机制
- Java gc垃圾回收机制
- JAVA gc垃圾回收机制
- JAVA gc垃圾回收机制
- Java gc(垃圾回收)机制
- JAVA gc垃圾回收机制
- JAVA gc垃圾回收机制
- GC java垃圾回收机制
- Java 垃圾回收机制GC
- [LeetCode]Longest Increasing Subsequence
- CentOS7 Oracle11g安装+图示
- 图片查看器
- [Android开发]使用XUtils框架出现的问题记
- Android的httpclient的post方法获取服务器端的数据(服务器端是get方法)
- java中的gc垃圾回收机制
- 【HTML学习】样式
- Android setAudioSource failed
- OO模式-Proxy模式<二>借助反射实现动态代理
- Jsp重定向
- linux chmod 使用方法
- Android和网页进行js交互的时候,json传参问题
- 经典编程题目
- android学习总结四:如何编写自己的Android.mk