JVM中高级java工程师面试题

说一下 jvm 的主要组成部分?

类加载器(ClassLoader)

运行时数据区(Runtime Data Area)

执行引擎(Execution Engine)

本地库接口(Native Interface)

STW(stop the world)是什么?

stop the world指的是GC触发时,整个应用程序线程都会被暂停

为什么需要STW(stop the world)

程序在运行时,不断的产生新的垃圾 这样就会导致在垃圾永远回收不完

JVM的生命周期

java的虚拟机种有两种线程,一种叫叫守护线程,一种叫非守护线程,

main函数就是个非守护线程,虚拟机的gc就是一个守护线程。java的虚拟机中,只要有任何非守护线程还没有结束,java虚拟机的实例都不会退出

方法区(jdk7的永久代)(JDK8的元空间)

jdk1.7运行时常量池、类型信息、字段、方法还是在永久代中,jdk1.8就吧这些移到元空间

1元空间与永久代之间最大的区别:元空间并不在虚拟机中,而是使用 本地内存

2.减少OOM异常

3,提高 Full GC 回收效率。

jdk8 ,jdk7 加载的类信息。

Java 虚拟机栈

虚拟机栈:

局部变量表,

操作数栈(1出栈,2入栈)

动态链接:所有的变量和方法引用都作为符号 保存在class文件的常量池里。

动态链接的作用通过这些符号去找 方法。

方法出口:1、执行引擎遇到任意一个方法返回的字节码指令,也就是所谓的正常完成出口。2、在方法执行的过程中遇到了异常

Java本地方法栈

本地方法栈和java虚拟机栈十分相似,差别不过是java虚拟机栈是为了java虚拟机执行字节码所服务,而本地方法栈则是为了执行native方法所服务的

程序计数器

内存空间小,线程私有。

程序计数器是一个记录着当前线程所执行的字节码的行号指示器。

执行引擎

就是将字节码指令翻译成操作系统指令。再由CPU去执行

本地接口方法

Native(方法) 可以理解是一个java调用非java代码的接口, 这个方法是用C/C++语言实现的,并且被编译成了DLL,由java去调用

可以作为GC Roots 的对象

就是变量(局部变量, 静态变量 常量 )等

java对象内容

1.对象头中的Mark Word(标记字)主要用来表示对象的线程锁状态GC状态标识

2.Klass Word是一个指Class的指针

3.数组长度也是占用64位

4.对象体

5.对齐填充

jvm 垃圾回收过程

引用计数器法:①每当有一个对象引用是,计数器加一,当计数器为0是对象死亡②缺点:无法解决循环引用的问题,假设A引用B,B引用A,那么这两个对象将不会被回收,造成内存泄漏

(2)可达性算法分析:

①通过一系列可作为GC Roots的节点为起始点,从这些节点开始往下搜索,所走过的路径称为引用链。 ②当一个对象到GC Roots节点没有引用链时,说明对象不可用

gc用的什么算法

复制算法:复制算法将内存划分为两个区间,A,B区 把A区存活的对象复制到B区,然后把A区清除

主要缺点有两个:

(1)效率问题:在对象存活率较高时,复制操作次数多,效率降低;

(2)空间问题:內存缩小了一半;需要空间分配担保(老年代

标记清除算法:遍历GC Root 标记存活的对象 ,再次遍历清除未标记的对象

它的主要缺点:1内存碎片

标记整理算法: 标记过程仍然与“标记-清除”算法一样,让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存

缺点:对象移动效率低

主要有下面三种方式

1:大对象直接进入老年代。比如很长的字符串,或者很大的数组等,参数-XX:PretenureSizeThreshold=3145728

2:长期存活的对象进入老年代。每次 Minor GC 而不被回收,这个值就会增  加 1 岁。当它的年龄到达一定的数值时,就会晋升到老年代中,可以通过参数-XX:MaxTenuringThreshold设置年龄阀值(默认是 15 岁)

3:(动态对象年龄判定)当 Survivor 空间中相同年龄所有对象的大小总和大于 Survivor 空间的一半,直接进入老年代。

4:空间分配担保:

分配担保是指年老代给新生代作分配担保,由于新生代使用复制算法进行垃圾回收,

而年老代使用标记-清除和标记-整理进行垃圾回收,使用复制算法的新生代才需要分配担保。

FullGC触发

1在发生Young GC的时候,虚拟机会检测之前每次晋升到老年代的平均大小是否大于年老代的剩余空间,如果大于,则直接进行Full GC;

2System.gc()也会触发Full GC

3堆中分配很多大的对象

CMS收集器:

基于"标记-清除"算法(不进行压缩操作,产生内存碎片);

指定使用CMS收集器;-XX:+UseConcMarkSweepGC":

初始标记(CMS initial mark)

仅标记一下GC Roots能直接关联到的对象; 需要"Stop The World"

并发标记(CMS concurrent mark)

进行GC Roots Tracing 的过程,找出存活对象且用户线程可并发执行。

重新标记:

为了修正并发标记期间因用户程序继续运作而导致标记变动需要" Stop The World"

并发清除(CMS concurrent make sweep)

回收所有的垃圾对象; 可以与用户线程一起工作

CMS收集器2个明显的缺点:

1对CPU资源非常敏感(并发标记,并发清除)

2浮动垃圾(清理阶段产生的垃圾,只能下次回收)

3内存碎片(标记算法的通病)

解决方法:

1.Compact 

"-XX:+UseCMSCompactAtFullCollection" 使得CMS出现上面这种情况时不进行Full GC,开启内存碎片的合并整理过程

2.Compaction

"-XX:+CMSFullGCsBeforeCompaction" 设置执行多少次不压缩的Full GC后,来一次压缩整理

G1收集器 :

Pause Millis

-XX:+UseG1GC -Xmx32g -XX:MaxGCPauseMillis=200

通过参数-XX:ParallelGCThreads进行指定GC工作的线程数量

-XX:+UseG1GC为开启G1垃圾收集器,-Xmx32g 设计堆内存的最大内存为32G,-XX:MaxGCPauseMillis=200设置GC的最大暂停时间为200ms

将堆内存划分成多个大小相等独立区域,每一个区域(Region)都可以根据需要,扮演新生代的Eden空间、Survivor空间,old空间。

另外Region中还有一类特殊的Humongous区域

-XX:NewRatio=4 相当于4+1 1/5新生代(eden,Survivor区),老年代4/5

-XX:SurvivorRatio=3相当于 3+1 Survivor区1/4 ,eden区3/4

Region的大小可以通过 -XX:G1HeapRegionSize参数指定

如果一个对象占用的空间超过了分区容量50%以上,G1收集器就认为这是一个巨型对象(Humongous)。

G1中提供了两种模式垃圾回收模式,young gc、mixed gc 使用的是混合算法。

young gc 使用的是复制算法

当所有eden region被耗尽无法申请内存时,就会触发一次young gc,

mixedgc

触发条件:-XX:InitiatingHeapOccupancyPercent设定的值则触发

初始标记

需要暂定所有线程,即STW,与CMS的初始标记一样

并发标记

与CMS的并发标记一样

最终标记

需要暂定所有线程(STW),与CMS的重新标记是一样的

筛选回收

需要STW,G1就不需要像CMS那样回收完后还要进行碎片整理,使用的是复制算法

Full GC

使用单线程标记、清理、压缩整理空闲出来一批Region来供下一次MixedGC使用, 性能会非常差,STW时间会很长。

G1垃圾收集器的特点

并行与并发

G1能充分利用CPU、多核环境下的硬件优势, 来缩短STW停顿时间。

分代收集

G1不需要其他收集器配合就能独立管理整个GC堆

空间整合

与CMS的标记-清理算法不同,G1从整体来看是标记-整理算法实现的收集器,从局部上来看是复制算法实现的。

可预测的停顿

这是G1相对于CMS的另一个大优势,降低停顿时间 ,还能建立可预测的停顿时间 参数-XX:MaxGCPauseMillis指定

什么场景适合使用G1

1垃圾回收时间特别长,超过1秒.

2堆内存空间大

3停顿时间是500ms以内

java cup过高原因

1while无限循,如cas 无限循环将调用CPU寄存器进行计数

2频繁的GC(Yong ,Mixed,full),它需要计算内存和调用寄存器

直接内存

不是虚拟机运行时数据区的一部分。

ByteBuffer.allocateDirect(2); //直接内存分配申请,通过MaxDirectMemorySize设置,默认与堆的最大值-Xmx参数值一致

Cleanerclean释放直接内存

直接内存在IO操作上具有更高的性能,因为它直接作用于本地系统的IO操作。

非直接内存如果要作IO操作,会先复制到直接内存,再利用本地IO处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值