Java JVM 垃圾回收

一、垃圾回收作用于“堆”和“非堆(方法区)”两个线程共享的部分。
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虚拟机》 周志明

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值