2020大厂面试之【JVM+GC】必考面试题讲解

简介: 2020大厂面试之【JVM+GC】必考面试题讲解

20200723092220992.png

一、JVM【JDK8】


1.1 JVM结构图


20200723091401671.png


1.2 GC Roots的理解


思路就是通过一系列名字为“”GC Roots“”的对象作为哦起点,开始向下搜索,如果一个对象到GC Roots没有任何引用链连接时候,则说名对象不可用。也即给他一个集合的引用作为跟出发,通过引用关系遍历对象图,能被遍历到的对象被判断为存活,没有的话就是死亡。




可以作为GC Roots的对象


虚拟机栈中的对象
方法区中的类静态属性引用的对象
方法区中常量引用的对象
本地方法栈中Native引用的对象


1.3 JVM调优的标配参数和X,XX参数


标配参数:

java -version

java -help


X参数:【了解】

-Xint: 解释执行

-Xcomp: 第一次使用编译成本地代码

-Xmixed:混合模式【默认的】


XX参数:

Boolean类型

-XX:+或者-某个属性值,+代表开启,-代表关闭

如何查看是否开启了某个参数


jps -l
jinfo -flag PrintGCDetails 4526
// 结果如下:
-XX:+PrintGCDetails 
表示激活了打印GC信息

KV设置类型


-XX:属性key=属性值value

如何设置元空间的大小???

jps -l
jinfo -flag MetaspaceSize 6350
// 默认21M
-XX:MetaspaceSize=21807104
// 程序运行调成1G
-XX:MetaspaceSize=1024m


jinfo举例


-Xms: -XX:InitialHeapSize
-Xmx:-XX:MaxHeapSize


1.4 JVM初始默认值


20200723092942527.png

1.5 JVM常用调优参数


20200723170525636.png



-Xms: -XX:InitialHeapSize 初始堆内存【存储空间】

-Xmx:-XX:MaxHeapSize 最大堆内存


-Xss:-XX:ThreadStackSize 设置单个线程栈空间的大小,一般默认为512k-1024k【运行空间】

一般0为出事的默认值

**-Xmn:**设置年轻代的大小

-XX:MetaspaceSize 设置元空间的大小,元空间不在虚拟机中,而是使用的是本地内存,仅受本地内存的限制。默认使用了20m左右

-XX:+PrintGCDetails 打印垃圾回收的细节情况

// 模拟产生OOM的情况下,查看垃圾回收的细节
JVM配置 -Xms:10m -Xmx:10m -XX:+PrintGCDetails 
程序设置50M大小的对象
byte[] byteArray = new byte[50 * 1024 * 1024];


20200724092540565.png

GC类型:

20200724092628736.png


FullGC:


20200724093050268.png

-XX:SurvivorRatio


20200724095606560.png

-XX:NewRatio

20200724100844115.png

-XX:MaxTenuringThreshold 设置垃圾回收的最大年龄

20200724103250931.png


二、强、软、弱、虚引用

20200724104231603.png



2.1 强引用Reference


当内存不足的时候,对于强引用对象,就算是出现OOM也不会对该对象进行回收。把一个对象赋值给一个引用变量,这个变量就是一个强引用。该对象的以后永远不会被JVM回收,经常造成内存泄漏OOM。

如果没有引用才可以被回收。


20200724105330523.png

2.2 软引用SoftReference


当内存足够不回收,不够就要回收,尽量不要OOM。

20200724105846700.png


结果:一个null 一个 有值

当内存不够用时候呢?

配置小内存,大对象试试

20200724110128533.png


结果:就发生了OOM,后面两个输出均为null


2.3 弱引用WeakReference


只要有弱引用就会回收,不管内存够不够用。


java.lang.ref.WeakReference


20200724110659263.png


结果:后两个全为null


2.4 虚引用PhantomReference


形同虚设,与其他引用均不同,并不会决定对象的生命周期。

必须与引用队列联合使用ReferenceQueue

跟踪回收的状态


三、GC垃圾回收


3.1 垃圾回收算法


1.引用计数

2.复制:内存开销

3.标记清除 :内存碎片

4.标记清除整理


3.2 垃圾回收器


这是垃圾回收算法的实现

1.Serial 串行垃圾回收器


他为单线程环境设计的只是用一个线程进行垃圾回收,会停止所有的用户线程


JVM参数:-XX:+UseSerialGC

开启后默认在Serial(Young区用) + Serial Old(Old区用)的收集器组合

新生代和老年代都会使用串行收集回收器,新生代使用复制算法,老年代使用标记-整理算法

2.Parallel 并行垃圾回收器

多个垃圾回收线程,用户线程暂停,适合于科学计算,大数据等弱交互场景。

就是串行回收器的并行版本

JVM参数:-XX:+UserParNewGC

ParNew(Young区用) + Serial Old的组合,新生代使用赋值算法,老年代使用标机-整理算法

3.CMS 并发标记清除垃圾回收器

用户线程和垃圾回收线程,不一定并行或者交替,适合于高并发场景。

JVM参数:-XX:UseConcMarkSweepGC


20200725095305328.png


【养老区】:

无法整理空间 碎片

4.G1

将堆内存分割成不同的区域然后并发的随其进行垃圾回收

JVM参数:-XX:+UseG1GC

横跨young old


20200725100543537.png


面向服务器的收集器

更高的并发

更少的延迟

整理空间更快

不需要很大的堆内存

不会产生很多内存碎片

用户可以指定停顿时间

目标为取代CMS

jdk7中有G1,jdk9中变成默认的垃圾回收器来替代CMS

总结:

20200725100008405.png

1: G1能充分利用多CPU、 多核环境硬件优势,尽量缩短STW。

2:G1整体上采用标记-整理算法,局部是通过复制算法,不会产生内存碎片。

3:宏观上看G1之中不再区分年轻代和老年代。把内存划分成多个独立的子区域(Region),可以近似理解为一个围棋的棋盘。

4:G1收集器里面讲整个的内存区都混合在一-起了 ,但其本身依然在小范围内要进行年轻代和老年代的区分,保留了新生代和老年代,但它们不再是物理隔离的,而是一部分Region的集合且不需要Region是连续的,也就是说依然会采用不同的GC方式来处理不同的区域。

5: G1虽然也是分代收集器,但整个内存分区不存在物理上的年轻代与老年代的区别,也不需要完全独立的survivor(to space)堆做复制 准备。G1只有逻辑上的分代概念,或者说每个分区都可能随G1的运行在不同代之间前后切换;


3.3 如何查看默认的垃圾回收器?


最后一个参数就是垃圾回收器的种类


java -XX:+PrintCommandLineFlags -version


20200724162147111.png


20200725085248855.png


3.4 JVM的Server/Client模式


  • 32位windows 默认是Client的JVM模式
  • 其他操作系统2G内存,2cpu以上的用Server模式
  • 64位 仅仅Server


3.5 JVM GC+Springboot部署调参


启动流程


springboot工程

maven clean

maven package

微服务启动,同时配置JVM GC的调优参数【内,外】

java -jar springbootxxxxx.war/jar


调参公式:


java -server JVM参数  -jar springbootxxxxx.war/jar


示例如下

// 1.参数调优
java -server -Xms1024m  -Xmx1024m  -XX:+UseG1GC -jar springbootxxxxx.war/jar
// 2.查看进程ID
jps -l 
// 3.查看信息
jinfo -flags 9969

四、Linux生产服务器变慢如何诊断?


操作步骤:


4.1 整机:top


或者 uptime 也可以

load average: 1.52, 0.98, 0.55

计算负载高: (1.52+0.98+0.55)/3 * 100% > 60%


4.2 CPU: vmstat

// 每2秒采样一次 一共采样3次
vmstat -n 2 3

20200725104616815.png


// 所有的CPU  idle空闲虑
mpstat -P ALL 2
// 详细信息
pidstat -u l -p 5103

4.3 内存:free

// 内存 MB单位
free -m
// 查看额外 采样次数2S
pidstat -p 5103 -r 2

4.4 硬盘:df


// 简单方便 GB
df -h


4.5 磁盘IO: iostat


iostat -xdk 2 3
// 磁盘块设备分布
rkB/s每秒读取数据量kB;
wkB/s每秒写入数据量kB:
svctm /O0请求的平均服务时间,单位毫秒:
await l/O请求的平均等待时间,单位毫秒;值越小,性能越好:
util 一秒中有百分几的时间用于/O操作。接近100%时,表示磁盘带宽跑满,需要优化程序或者增加磁盘;
rkB/s、wkB/s根据 系统应用不同会有不同的值,但有规律遵循:长期、超大数据读写,肯定不正常,需要优化程序读取。
svctm的值与await的值很接近,表示几乎没有I/O等待,磁盘性能好,
如果await的值远高于svctm的值,则表示1/O队列等待 太长,需要优化程序或更换更快磁
// 具体信息
pidstat -d 2 -p 5103


4.6 网络IO:ifstat


// 采样频率1S
ifstat 1


目录
相关文章
|
3天前
|
存储 缓存 前端开发
100道 IT名企前端面试真题,Web前端阿里等大厂面试题汇总
100道 IT名企前端面试真题,Web前端阿里等大厂面试题汇总
|
3天前
|
移动开发 前端开发 JavaScript
【前端面试】前端面试题300道~~熬夜吐血整理,2024年最新大厂面试经验分享稿
【前端面试】前端面试题300道~~熬夜吐血整理,2024年最新大厂面试经验分享稿
|
3天前
|
移动开发 前端开发 JavaScript
Web前端开发之面试题全解析 一(3),前端面试题背不下来怎么办
Web前端开发之面试题全解析 一(3),前端面试题背不下来怎么办
|
3天前
|
前端开发 算法 搜索推荐
Web前端开发之面试题全解析 一(1),2024年最新前端组件化面试
Web前端开发之面试题全解析 一(1),2024年最新前端组件化面试
|
3天前
|
存储 缓存 JavaScript
web前端常见的面试题汇总(一),web前端面试题目
web前端常见的面试题汇总(一),web前端面试题目
|
3天前
|
存储 缓存 前端开发
web前端常见的面试题总结,2024年最新面试时有哪些技巧
web前端常见的面试题总结,2024年最新面试时有哪些技巧
web前端常见的面试题总结,2024年最新面试时有哪些技巧
|
3天前
|
JSON JavaScript 前端开发
web前端入门到实战:32道常见的js面试题,2024年最新秋招是直接面试吗
web前端入门到实战:32道常见的js面试题,2024年最新秋招是直接面试吗
|
3天前
|
JavaScript 前端开发 程序员
web前端入门到实战:32道常见的js面试题(1),面试哪些
web前端入门到实战:32道常见的js面试题(1),面试哪些
|
3天前
|
前端开发 JavaScript
web前端JS高阶面试题,2024我的前端大厂面试之旅
web前端JS高阶面试题,2024我的前端大厂面试之旅
|
3天前
|
JavaScript 前端开发
web前端JS高阶面试题(1),高级开发工程师面试
web前端JS高阶面试题(1),高级开发工程师面试