JVM常见面试题解析

什么情况下会发生栈内存溢出

  • 栈是线程私有的,他的生命周期与线程相同,每个方法在执行的时候都会创建一个栈帧,用来存储 局部变量表,操作数栈,动态链接,方法出口等信息。局部变量表又包含基本数据类型,对象引用 类型
  • 如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常,方法递 归调用产生这种结果。
  • 如果Java虚拟机栈可以动态扩展,并且扩展的动作已经尝试过,但是无法申请到足够的内存去完成 扩展,或者在新建立线程的时候没有足够的内存去创建对应的虚拟机栈,那么Java虚拟机将抛出一 个OutOfMemory 异常。(线程启动过多)
  • 参数 -Xss 去调整JVM栈的大小

 详解JVM内存模型

 

  •  程序计数器 :当前线程所执行的字节码的行号指示器,用于记录正在执行的虚拟机字节指令地址,线程私有
  • 虚拟机栈:存放基本的数据类型
  • 方法栈:存放native方法
  • 堆:Java内存最大的一块儿,对象、数组等都在这儿,GC回收的地方,线程共享
  • 方法区:存放已经加载的类信息,常量、静态变量等等(即永久带),回收目标主要是常量池的回收和类型的卸载,线程共享

 JVM内存为什么要分成新生代,老年代,持久代。新生代中为什么 要分为Eden和Survivor

        先讲一下JAVA堆,新生代的划分,再谈谈它们之间的转化,相互之间一些参数的配置(如: – XX:NewRatio,–XX:SurvivorRatio等),再解释为什么要这样划分,最好加一点自己的理解。

  • 共享区域划分 
    共享内存区:持久代+ 堆
    持久代:方法+其他
    堆:老年代+新生代
    新生代:Eden+s0+s1
  • 一些参数的配置
    默认的,新生代 ( Young ) 与老年代 ( Old ) 的比例的值为 1:2 ,可以通过参数 –XX:NewRatio 配 置。
    默认的,Edem : from : to = 8 : 1 : 1 ( 可以通过参数 –XX:SurvivorRatio 来设定)
    Survivor区中的对象被复制次数为15(对应虚拟机参数 -XX:+MaxTenuringThreshold)
  • 为什么要分为Eden和Survivor?为什么要设置两个Survivor区
            如果没有Survivor,Eden区每进行一次Minor GC,存活的对象就会被送到老年代。老年代很快被 填满,触发Major GC.老年代的内存空间远大于新生代,进行一次Full GC消耗的时间比Minor GC 长得多,所以需要分为Eden和Survivor。
           Survivor的存在意义,就是减少被送到老年代的对象,进而减少Full GC的发生,Survivor的预筛选 保证,只有经历16次Minor GC还能在新生代中存活的对象,才会被送到老年代。
            设置两个Survivor区最大的好处就是解决了碎片化,刚刚新建的对象在Eden中,经历一次Minor GC,Eden中的存活对象就会被移动到第一块survivor space S0,Eden被清空;等Eden区再满 了,就再触发一次Minor GC,Eden和S0中的存活对象又会被复制送入第二块survivor space S1(这个过程非常重要,因为这种复制算法保证了S1中来自S0和Eden两部分的存活对象占用连续 的内存空间,避免了碎片化的发生)

 

JVM中一次完整的GC流程是怎样的,对象如何晋升到老年代

....

等等。。 都准备好了放在网盘里了

链接:https://pan.baidu.com/s/1JvuwMzoybCJBP47C129uRg 
提取码:5e01

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值