JVM扫盲(一)

188 阅读3分钟

java JVM A

Java虚拟机

  1. 说一下JVM的内存结构?

    参考:

    blog.51cto.com/lizhenliang…

    image-20210904161748264

    JDK1.6、JDK1.7、JDK1.8有些不同

    相同:java虚拟机栈、本地方法栈、程序计算器

    不同:

    常量池有:运行时常量池(final修饰局部变量)、类常量、字符串常量池

    JDK1.6:方法区[含全部常量池]、堆

    JDK1.7:方法区[含运行时常量池、类常量池]、堆[字符串常量池]

    JDK1.8:移除了方法区,由元数据区(也有翻译是MetaSpace元空间)代替,元数据区和方法区类似,最大的区别就是元数据区不在JVM中,而是使用本地内存。

    堆是经常面试会提问的,堆是内存空间占据最大的一块区域。几乎所有的对象都放在堆。

    分为:年轻代(1/3)[Eden、S01、S02;比例8:1:1,可调]、老年代(2/3)

    • 方法区

      java虚拟机规范中,把方法区定义为堆的一个逻辑部分。方法区存放的信息一般都是长期存在的,它又是对的逻辑分区,所以用堆的划分方法,把方法区划分为”永久代“。

    • java虚拟机栈

    • 本地方法栈

    • 程序计算器

    • 元数据

      JVM内存结构-树状

      image-20210904203438799

img

为什么要移除移除方法区,用其他XXX方式代替?是怎么移除的,原来在方法区的东西放哪里了?

为了融合新技术,融合HotSpot JVM与JRockitVM(新JVM技术)而做出的改变,因为JRockit没有方法区(永久代)。

原来的方法区由元数据区实现,不在JVM中,在本地内存。

元数据区(元空间)有两个参数:

MetaspaceSize:初始元空间大小,控制发送GC阀值

MaxMetaspaceSize:限制元空间大小上限,防止异常占用过多物理内存。

image-20210904163748510

对象年代迁移过程

image-20210904205028601

S0和S1始终保持一个是空的。在Survivor倒腾了16次之后,才会移到Old区,这个次数是可以调的吗?

各区存在的意义和设置比例的合理性:

目的都是减少内存碎片,减少GC,针对不同的年代用不同的GC算法,算法扬长避短。

有了Survivor区,可以减少被送到Old区的对象,从而减少Full GC,经过了Survivor区的筛选保证,只有经历了16次的Minor GC还在存活的对象,才会送到Old区。

为什么什么 Eden:S0:S1 比例是 8: 1 : 1?

大部分的对象(约98%)存活时间不长的。

2.栈帧里面包含哪些东西?

image-20210905115901933

  1. 程序计数器有什么作用?

  2. 字符串常量存放在哪个区域?

    回收算法和垃圾回收器

    1. 你熟悉哪些垃圾收集算法?

      image-20210905114030694

    2. java里有哪些引用类型?

      强、软、弱、虚

    3. JVM怎么判断一个对象是不是要回收?

      标记对象

      1、引用计数法,每引用一次,计数加1,减少一个引用,计数减1;

      2、可达性分析,通过一系列GC ROOTS对象作为起点,向下搜索,深度遍历,搜索过的对象没有改对象的话,则对象不可用。效率比较低吧?FullGC用?

  3. GC Roots 有哪些?

    首先肯定不是堆里面的,是堆之外的。

    1、虚拟机栈(栈帧中的本地变量表)中引用的对象。   2、方法区[元空间]中类静态属性引用的对象。 3、方法区[元空间]中常量引用的对象。 4、本地方法栈中JNI(即一般说的Native方法)引用的对象。