转自:https://thinkwon.blog.csdn.net/article/details/104390752
1.
栈和堆的区别
- 堆因为是不连续的,所以分配的内存是在
运行期
确认的,因此大小不固定。栈是连续的,所以分配的内存大小要在编译期
就确认,大小是固定的。 - 堆存放的是对象的实例和数组。栈存放:局部变量,操作数栈,返回结果。
-
PS:静态变量放在方法区;静态的对象还是放在堆。
2.
说一下类装载的执行过程?
类装载分为以下 5 个步骤:
- 加载:根据查找路径找到相应的 class 文件然后导入;
- 验证:检查加载的 class 文件的正确性;
- 准备:给类中的静态变量分配内存空间;
- 解析:虚拟机将常量池中的符号引用替换成直接引用的过程。符号引用就理解为一个标示,而在直接引用直接指向内存中的地址;
- 初始化:对静态变量和静态代码块执行初始化工作。
什么是双亲委派模型?
3.
CMS原理
适合多CPU,频繁和用户交互的业务场景,追求的是停顿时间最短,采用标记清除的回收算法(因为标记清除不会涉及存活对象的移动:复制和压缩,从而降低STW的时间)
回收4个阶段
- 初始标记:STW,快速获取到老年代中的GC Roots对象,以及遍历新生代中GC Roots对象引用到老年代中的对象, 默认是单线程执行,也可以设置多线程数并行进行。
- 并发标记:并发客户线程,只分配一个线程来根据初始标记里面的对象开始,逐个标记 初始标记成功的对象的引用的对象。如果并发期间,对象的引用关系发生改变,则会被标记为dirty对象。
- 重新标记:STW,修正并发标记期间,引用关系的改变,这个过程比初始标记稍长。
- 并发清除:专门分配一个线程来清除标记过的对象,不影响用户操作,此阶段会有新的浮动垃圾生成,如果太多,会造成PromotionFailure
CMS的缺点
- 对CPU资源敏感,因为在并发标记、并发清除的时候都需要占用一个单独的线程来完成操作,如果CPU为2的话,那么就只有1个CPU能干活,一个CPU在GC
- 无法处理浮动垃圾,也就是每次GC都扫不干净,因为并发清除的过程中,还会有新的垃圾产生,而且如果这个阶段新的垃圾导致空间不足,会PromotionFailure
- 基于标记清除算法会存在很多碎片,空间利用率不高,需要配置压缩参数,但是在压缩的过程中STW的时间会延长
4.
G1垃圾回收器原理
初始标记-》并发标记-》最终标记-》筛选回收(复制)
优点:
1、空间整合:g1使用Region独立区域概念,g1利用的是标记复制法,不会产生垃圾碎片
2、分代收集:g1可以自己管理新生代和老年代
3、并行于并发:g1可以通过机器的多核来并发处理 stop - The - world停顿,减少停顿时间,并且可不停顿java线程执行GC动作,可通过并发方式让GC和java程序同时执行。
4、可预测停顿:g1除了追求停顿时间,还建立了可预测停顿时间模型,能让制定的M毫秒时间片段内,消耗在垃圾回收器上的时间不超过N毫秒
最大的区别是出现了Region区块概念,可对回收价值和成本进行排序回收,根据GC期望时间回收,还出现了member set概念,
G1收集器之所以能建立可预测的停顿时间模型,是因为它可以有计划地避免在整个Java堆中进行全区域的垃圾收集。G1会通过一个合理的计算模型,计算出每个Region的收集成本并量化,这样一来,收集器在给定了“停顿”时间限制的情况下,总是能选择一组恰当的Regions作为收集目标,让其收集开销满足这个限制条件,以此达到实时收集的目的。