java JVM A
Java虚拟机
-
说一下JVM的内存结构?
参考:
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内存结构-树状
为什么要移除移除方法区,用其他XXX方式代替?是怎么移除的,原来在方法区的东西放哪里了?
为了融合新技术,融合HotSpot JVM与JRockitVM(新JVM技术)而做出的改变,因为JRockit没有方法区(永久代)。
原来的方法区由元数据区实现,不在JVM中,在本地内存。
元数据区(元空间)有两个参数:
MetaspaceSize:初始元空间大小,控制发送GC阀值
MaxMetaspaceSize:限制元空间大小上限,防止异常占用过多物理内存。
对象年代迁移过程
S0和S1始终保持一个是空的。在Survivor倒腾了16次之后,才会移到Old区,这个次数是可以调的吗?
各区存在的意义和设置比例的合理性:
目的都是减少内存碎片,减少GC,针对不同的年代用不同的GC算法,算法扬长避短。
有了Survivor区,可以减少被送到Old区的对象,从而减少Full GC,经过了Survivor区的筛选保证,只有经历了16次的Minor GC还在存活的对象,才会送到Old区。
为什么什么 Eden:S0:S1 比例是 8: 1 : 1?
大部分的对象(约98%)存活时间不长的。
2.栈帧里面包含哪些东西?
-
程序计数器有什么作用?
-
字符串常量存放在哪个区域?
回收算法和垃圾回收器
-
你熟悉哪些垃圾收集算法?
-
java里有哪些引用类型?
强、软、弱、虚
-
JVM怎么判断一个对象是不是要回收?
标记对象
1、引用计数法,每引用一次,计数加1,减少一个引用,计数减1;
2、可达性分析,通过一系列GC ROOTS对象作为起点,向下搜索,深度遍历,搜索过的对象没有改对象的话,则对象不可用。效率比较低吧?FullGC用?
-
-
GC Roots 有哪些?
首先肯定不是堆里面的,是堆之外的。
1、虚拟机栈(栈帧中的本地变量表)中引用的对象。 2、方法区[元空间]中类静态属性引用的对象。 3、方法区[元空间]中常量引用的对象。 4、本地方法栈中JNI(即一般说的Native方法)引用的对象。