Java笔试题常见知识点:Java内存模型,JVM内存配置参数,垃圾回收算法
Java内存模型(JMM)
JVM 内存共分为虚拟机栈、堆、方法区、程序计数器、本地方法栈五个部分。
线程私有:程序计数器、虚拟机栈、本地方法栈
线程共享:元空间、常量池、Java堆、方法区
(1) 程序计数器:是逻辑计数器,当前线程所指向的字节码行号指示器(和线程是一对一关系),对Java方法计数,不会发生内存泄漏
(2) 虚拟机栈(Stack):包含多个栈帧,各个线程有自己的栈空间
问:递归为什么会引发StackOverflowError异常?(要限制递归次数或用循环代替递归)
答:递归过深,栈帧数超过虚拟栈深度
(3) 本地方法栈:与虚拟机栈相似,主要用于标注了native的方法
(4) 元空间:
问:元空间MetaSpace和永久代PermGen的区别?
答:元空间使用本地内存,永久代使用jvm内存(容易出现性能问题和内存泄漏)
(5) Java堆:实例对象的分配区域(GC管理的主要区域)
JVM内存区域组成
VM内存区域总体分两类,heap区 和 非heap 区 。
-
heap区: 堆区分为Young Gen(新生代),Tenured Gen(老年代-养老区)。
其中新生代又分为Eden Space(伊甸园)、Survivor Space(幸存者区)。 -
非heap区: Code Cache(代码缓存区)、Perm Gen(永久代)、Jvm Stack(java虚拟机栈)、Local Method Statck(本地方法栈)。
由上图可看出有两个Survivor区:S0,S1
只有一个Eden区
JVM几个常见的内存配置参数
-Xmx :堆的最大值
-Xms :堆的最小值
-Xmn :堆年轻代大小
-XXSurvivorRatio:Eden区和单个Survior区的占用比例.
例题:对于jvm内存配置参数:
-Xmx10240m -Xms10240m -Xmn5120m -XXSurvivorRatio=3
其最小内存值和Survior区总大小分别是:
a. 5120m,1024m
b.5120m,2048m
c.10240m,1024m
d.10240m,2048m
答案是:d.
Survior区有两个,就是图中的S0和S1,而Eden区只有一个,
-XXSurvivorRatio参数是Eden区和单个Survior区的比例,
5120m是整个年轻代的大小(包括一个Eden和两个Survivor),一个Eden顶三个Survivor,
所以应该有(3+1+1)*Survior=5120m,图中问的是Survior总大小(需乘2),显然是d.
垃圾回收算法
判断一块内存空间是否符合垃圾收集器收集的标准有哪些?
- 给对象赋予了空值null,以下再没有调用过,
- 给对象赋予了新值,即 重新分配了内存空间。
垃圾回收算法介绍
(1) 标记清除算法(利用对象引用图,回收未被标记的对象)
缺点:使内存碎片化
(2) 复制回收算法:需要两倍存储空间:对象面(创建对象)和空闲面
存活的对象从对象面复制到空闲面,再将对象面内存清除
解决碎片化问题,适用于对象存活率低的场景(多用于回收年轻代)
(3) 标记整理算法: 标记存活对象,移动整理所有存活对象,最后将末端不被引用对象全部回收
解决碎片化问题,适用于对象存活率高的场景(多用于回收老年代)
(4) 分代回收算法:(垃圾回收的组合,不同生命周期的对象采用不同垃圾回收算法)
分代回收算法中不同代采用的垃圾回收算法
年轻代:复制回收算法,因为存活下来的对象是少数,所需要复制的对象少
老年代:标记整理算法,因为老年代对象存活多,不适合采用复制算法