码迷,mamicode.com
首页 > 编程语言 > 详细

Java JVM 垃圾回收

时间:2015-07-18 20:02:11      阅读:129      评论:0      收藏:0      [点我收藏+]

标签:jvm   java   

一、垃圾回收作用于“堆”和“非堆(方法区)”两个线程共享的部分。
1、堆:
  堆的主要存放“生成的对象”和“开辟的数组”。
  面试的时候可能会问道,是不是所有的对象都存在于堆上?答案是否定的,当前虚拟机优化技术的发展,其中出现了逃逸分析(如果一个方法中生成的对象没有被其他方法或者线程使用,那么就是不逃逸的),如果对象不逃逸,那么就会把对象分配到栈空间上。另,网上有人还列举了TLAB,但是TLAB是存在于Eden之上的。
  技术分享
  如上图,我们来分析下对的组成,堆分为“Young(新生的)”和“Old(老年代)”两部分,其中Young中又分为一个“Eden”和两个“Survivor”。
  1)大部分“对象”会分配到Eden中,如果Eden空间不够用了,将会发起Minor GC,会将Eden中存活的对象和其中一个Survivor中存活并且没有晋升到Old的对象,复制到另一个Survivor中。
  如果Survivor中的空间不够用,将会将剩余的对象复制到Old区域中。(其中的限制,看4))
  注:任何时候,两个Survivor都只有一个被利用,且默认的时候Eden:Survivor=8:1。
  2)大对象(需要很长的连续空间,如很长的字符串、数组)直接分配到Old区域。
  3)在1)中,Minor GC之后,原先在Survivor的对象如果依旧在其中,那么他的”年龄“将会+1,如果年龄值>15(由-XX:MaxTenuringThreshold设置),将会晋升至Old区域。
  或者,在Survivor中相同年龄的对象占了其空间了一半以上,此时年龄大于前者的都会直接晋级到Old区域。
  4)以上晋升或者拷贝到Old区域的前提是,Old有足够的连续空间能容纳Young中所有对象的大小的情况;如果不够,将会在Old中进行Full GC。

2、非堆(方法区)
  方法区回收的主要动作是“常量池”清理和“类型卸载”
  1)常量池
 包括:常量,【类(接口)、方法、字符】的符号引用
 上述中,如果没有被引用,将可以被回收。
 2)类型卸载
 (1)不再存在实例
 (2)相应的ClassLoader被卸载
 (3)java.lang.Class对象不再引用,也即不再有反射操作。
 之后,就“可以”被回收。

二、附带复习下虚拟机运行时数据
  1、程序计数器
  2、Java虚拟机栈(线程私有,方法堆出即销毁)
    每个方法有会建立一个真栈,其中包括“局部变量表”,“操作数栈”,“动态链接”,“方法出口”等。
    其中局部变量表包括:
      1)基本数据类型,int long等
      2)对象的引用
      3)returnAddress类型
  3、本地方法栈(线程私有)被Native方法使用
  4、堆(会被垃圾回收)
  5、非堆(会被垃圾回收)

作者:林子木
博客地址:http://blog.csdn.net/wolinxuebin/
参考资料:《深入理解Java虚拟机》 周志明

版权声明:本文为博主原创文章,未经博主允许不得转载。

Java JVM 垃圾回收

标签:jvm   java   

原文地址:http://blog.csdn.net/wolinxuebin/article/details/46944551

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!