• jvm


    https://www.jianshu.com/p/9885ac7eac98

    这是在面试中碰到的问题,现在做一下总结:

    面试题:对象进入堆内存中,怎么从Eden区转入Survivor区,过程是怎么样的?新生代的内存为什么这么分配?

    首先讲这问题大部分资料讲的都不是很明确,这里也只是对大致过程做一些整理。

    一、对象的回收过程

    Java堆内存的空间分配如图:

     
    堆内存分配

    新生代的内存分配说明:

    Eden:主要是存放新增的对象,由于Eden区的对象都有一个特点,就是生命周期比较短,所以在每一次的GC都会将保存的对象清理回收。Eden区经历一次gc会清理掉大量的对象,如果此时存活的对象很多,而且大于Survivor区能公接收的范围,这些对象就会进入老年代。反之进入To Survivor区,minorGC完成之后,To 与 From完成角色互换,此时的To Survivor区变成下一次的From Survivor区。

    From/To : 存放经历gc存活的对象,在这两块内存区域的对象也不是会一直存活,VM为每个对象设定了一个年龄,进入Survivor区对象的年龄变为1,此后每经历一次GC,年龄就会增加1,到达设定的年龄阈值(-XX:MaxTenuringThreshold,默认15),对象就会进入老年代,如果相同年龄的对象占用内存超过Survivor区内存的一半也会直接进入老年代。

    到此回答完了面试问题。下面做一些问题的扩展,对象回收的判定,回收算法,垃圾回收器等


    二、对象的回收判断:

    1、引用计数法:给每个对象添加一个引用计数器,每当有一个对象引用它,计数器增加1,引用失效时计数器减1。任何时刻计数器为0就判定位没有对象引用。实际的VM回收过程中,并没有按照引用计数法判断对象是否存活。

    2、可达性分析算法:Java是根据该算法判定对象的回收。基本思路:每个对象的创建都是以GC Root作为对象的起点,每发生一次对象引用,就会往引用链中增加一个对象,根对象结束了生命周期,引用的对象就没有GC Root,当发生GC时,这些没用根对象的引用就会被回收。

    三、垃圾回收算法:

    标记清除:

    分为两个阶段,标记,清除,被标记的对象会在标记结束有被清除回收。但由于回收的对象是分散的,所以就会导致内存碎片化严重。

    复制算法:

    将内存分为容量大小相等的两块,当发生GC之后,将from的对象,复制到to区,避免了内存碎片,但也造成空间浪费。

    标记整理:

    标记完存活的对象之后,将存活的对象集中存放。

    分代收集:

    按照对象的特性区分年轻代,老年代,根据对象的特性选择对应的回收算法。年轻代,存活时间短选择复制算法,老年代选择标记清除或标记整理。

    四、垃圾回收器:

     
    新生代回收器
     
    老年代回收器

    五、JVM的内存分配

    JVM运行时的内存分配:

    线程私有:

    程序计数器(指示当前指令地址)、Java栈(运行出入口方法信息)、本地方法区(native方法)

    线程共享:堆,方法区(包含运行常量池,保存VM加载的类的信息,常量,静态变量)

     
    运行时内存

    在对JVM进行参数调优,对垃圾回收器的调整比较少,一般是对内存分配进行跳转,下图是内存分配的参数示意图。

     
    JVM参数分配




  • 相关阅读:
    登录远程服务器运行的程序,退出服务器仍然运行的方法
    python爬虫错误
    python将字符转换为字典
    shell中$(( )) 与 $( ) 还有${ }的区别
    JavaBean 开发入门
    反射机制 动态代理
    反射机制的深入应用
    反射机制 反射的应用 ---取得类的结构
    反射机制 CLass类的使用
    JSP 的九大内置对象
  • 原文地址:https://www.cnblogs.com/Treesir/p/11765136.html
Copyright © 2020-2023  润新知