IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> jvm垃圾回收和jvm调优介绍--Java之jvm -> 正文阅读

[Java知识库]jvm垃圾回收和jvm调优介绍--Java之jvm

我从以下五个方向介绍:

  1. 如何判断对象可以回收
  2. 垃圾回收算法
  3. 分代垃圾回收
  4. 垃圾回收器
  5. 垃圾回收调优

1. 如何判断对象可以回

1.1 引用计数法(Java没有采用这种算法)

一个对象别引用一次,对象就会加一。直到为零时可以被回收。

互相引用会导致无法回收(引用次数保持为1)

1.2 可达性分析算法

Java 虚拟机中的垃圾回收器采用可达性分析来探索所有存活的对象

扫描堆中的对象,看是否能够沿着 GC Root对象 为起点的引用链找到该对象,找不到,表示可以 回收

导出GC Root对象的文件命令:jmap –dump:format=b,live,file=test.bin 进程id

可以下载内存分析工具(MAT) Eclipse Memory Analyzer 进行分析

哪些对象可以作为 GC Root ?? Java内引用的。

1.3 四种引用

1. 强引用:只有所有 GC Roots 对象都不通过【强引用】引用该对象,该对象才能被垃圾回收(new对象,等号赋值都是强引用)

2. 软引用(SoftReference):仅有软引用引用该对象时,在垃圾回收后,内存(堆空间)仍不足时会再次出发垃圾回收,回收软引对象;可以配合引用队列来释放软引用自身

用法:内存小,不重要的内容,适合做缓存,比如图片访问快点就做软引用。

?public static void main(String[] args) {
??? List<SoftReference<
byte[]>> list = new ArrayList<>();
???
// 引用队列
??? ReferenceQueue<byte[]> queue = new ReferenceQueue<>();
???
for (int i = 0; i < 5; i++) {
???????
// 关联了引用队列, 当软引用所关联的 byte[]被回收时,软引用自己会加入到 queue 中去
??????? SoftReference<byte[]> ref = new SoftReference<>(new byte[1024 * 1024 * 10], queue);
??????? System.
out.println(ref.get());
??????? list.add(ref);
??????? System.
out.println(list.size());
???
}
??? // 从队列中获取无用的 软引用对象,并移除
??? Reference<? extends byte[]> poll = queue.poll();
???
while( poll != null) {
??????? list.remove(poll);
??
?????poll = queue.poll();
??? }

??? for (SoftReference<byte[]> reference : list) {
??????? System.
out.println(reference.get());
??? }

}

3. 弱引用(WeakReference):仅有弱引用引用该对象时,在垃圾回收时,无论内存是否充足,都会回收弱引用对象;可以配合引用队列来释放弱引用自身

用法:解决某些地方的内存泄露问题

相关面试题:开发中使用过weakHashMap吗?(引用的数据可以被及时回收)

4. 虚引用(PhantomReference):必须配合引用队列使用,主要配合ByteBu?er 使用,被引用对象回收时,会将虚引用入队,由Reference Handler 线程调用虚引用相关方法释放直接内存

5. 终结器引用(FinalReference):无需手动编码,但其内部配合引用队列使用,在垃圾回收时,终结器引用入队(被引用对象暂时没有被回收),再由 Finalizer 线程通过终结器引用找到被引用对象并调用它的 finalize 方法,第二次 GC 时才能回收被引用对象,效率太低

2. 垃圾回收算法

2.1 标记清除

定义: Mark Sweep

优点:速度较快(记录内存的起始地址进行清理)

缺点:会造成内存碎片

2.2 标记整理

定义:Mark Compact

优点:速度慢(清理后再进行整理,对象要移动,内存地址也会变)

缺点:没有内存碎片(存活较多)

2.3 复制

定义:Copy(有用的对象复制到to,复制完成后from和to再交换位置)

优点:不会有内存碎片

缺点:需要占用双倍内存空间

3. 分代垃圾回收(堆内存)

◎对象首先分配在伊甸园区域

◎新生代空间不足时,触发minor gc(新生代垃圾回收),伊甸园和 from 存活的对象使用 copy 复制到 to 中,存活的对象年龄加 1并且交换 from和to

◎minor gc 会引发 stop the world,暂停其它用户的线程,等垃圾回收结束,用户线程才恢复运行

◎当对象寿命超过阈值时,会晋升至老年代,最大寿命是15(4bit)(空间不足,可能要不了15次就会进入老年代)

◎当老年代空间不足,会先尝试触发 minor gc,如果之后空间仍不足,那么触发 full gc,STW的时间更长

3.1 相关 VM 参数

含义

参数

堆初始大小

-Xms

堆最大大小

-Xmx 或 -XX:MaxHeapSize=size

新生代大小

-Xmn 或 (-XX:NewSize=size + -XX:MaxNewSize=size )

幸存区比例(动态)

-XX:InitialSurvivorRatio=ratio 和 -XX:+UseAdaptiveSizePolicy

幸存区比例

-XX:SurvivorRatio=ratio

晋升阈值

-XX:MaxTenuringThreshold=threshold

晋升详情

-XX:+PrintTenuringDistribution

GC详情

-XX:+PrintGCDetails -verbose:gc

FullGC 前 MinorGC

-XX:+ScavengeBeforeFullGC

?

4. 垃圾回收器(cms三种)

三种形式:

1. 串行

◎单线程

◎堆内存较小,适合个人电脑

2. 吞吐量优先

◎多线程

◎堆内存较大,多核 cpu

◎让单位时间内,STW 的时间最短 0.2 0.2 = 0.4,垃圾回收时间占比最低,这样就称吞吐量高

3. 响应时间优先

◎多线程

◎堆内存较大,多核 cpu

◎尽可能让单次 STW 的时间最短 0.1 0.1 0.1 0.1 0.1 = 0.5

4.1 串行

-XX:+UseSerialGC = Serial + SerialOld(复制 + 标记整理)

4.2 吞吐量优先

-XX:+UseParallelGC ~ -XX:+UseParallelOldGC

-XX:+UseAdaptiveSizePolicy?? (自适应调节新生代和老年代大小)

-XX:GCTimeRatio=ratio? (自适应垃圾回收频次和时间)

-XX:MaxGCPauseMillis=ms??

-XX:ParallelGCThreads=n? (指定线程数)

4.3 响应时间优先

-XX:+UseConcMarkSweepGC ~ -XX:+UseParNewGC ~ SerialOld

-XX:ParallelGCThreads=n ~ -XX:ConcGCThreads=threads

-XX:CMSInitiatingOccupancyFraction=percent

-XX:+CMSScavengeBeforeRemark

?

4.4 G1

定义:Garbage First

◎ 2004 论文发布

◎ 2009 JDK 6u14 体验

◎ 2012 JDK 7u4 官方支持

◎ 2017 JDK 9 默认

适用场景

◎ 同时注重吞吐量(Throughput)和低延迟(Low latency),默认的暂停目标是 200 ms

◎ 超大堆内存,会将堆划分为多个大小相等的 Region

◎ 整体上是标记+整理算法,两个区域之间是复制算法

相关 JVM 参数

-XX:+UseG1GC

-XX:G1HeapRegionSize=size

-XX:MaxGCPauseMillis=time

4.4.1) G1 垃圾回收阶段

4.4.2) Young Collection

STW

4.4.3) Young Collection + CM

?Young GC 时会进行 GC Root 的初始标记 ?老年代占用堆空间比例达到阈值时,进行并发标记(不会 STW),由下面的 JVM 参数决定

-XX:InitiatingHeapOccupancyPercent=percent (默认45%

?

4.4.4) Mixed Collection

会对 E、S、O 进行全面垃圾回收

最终标记(Remark)会 STW 拷贝存活(Evacuation)会 STW

-XX:MaxGCPauseMillis=ms(优先回收占用较大的内存,不一定全部回收)

?

4.4.5) Full GC

1. SerialGC

新生代内存不足发生的垃圾收集 - minor gc

老年代内存不足发生的垃圾收集 - full gc

2. ParallelGC

新生代内存不足发生的垃圾收集 - minor gc

老年代内存不足发生的垃圾收集 - full gc

3. CMS

新生代内存不足发生的垃圾收集 - minor gc

老年代内存不足

4. G1

新生代内存不足发生的垃圾收集 - minor gc

老年代内存不足(老年代在堆内存占比45%,触发并发标记和混合收集阶段)

?

4.4.6) Young Collection 跨代引用

新生代回收的跨代引用(老年代引用新生代)问题

卡表与 Remembered Set

在引用变更时通过 post-write barrier + dirty card queue concurrent refinement

threads 更新 Remembered Set

4.4.7) Remark(并发标记+重新标记)

pre-write barrier(写屏障) + satb_mark_queue(队列)

对象引用发生变化会进入队列

4.4.8) JDK 8u20 字符串去重

优点:节省大量内存

缺点:略微多占用了 cpu 时间,新生代回收时间略微增加

-XX:+UseStringDeduplication默认启用

String s1 = new String("hello"); // char[]{'h','e','l','l','o'}

String s2 = new String("hello"); // char[]{'h','e','l','l','o'}

将所有新分配的字符串放入一个队列

当新生代回收时,G1并发检查是否有字符串重复如果它们值一样,让它们引用同一个 char[]

注意,与 String.intern() 不一样

String.intern() 关注的是字符串对象

而字符串去重关注的是 char[]

在 JVM 内部,使用了不同的字符串表

4.4.9) JDK 8u40 并发标记类卸载

所有对象都经过并发标记后,就能知道哪些类不再被使用,当一个类加载器的所有类都不再使用,则卸载它所加载的所有类

-XX:+ClassUnloadingWithConcurrentMark 默认启用

4.4.10) JDK 8u60 回收巨型对象

一个对象大于 region 的一半时,称之为巨型对象

G1 不会对巨型对象进行拷贝

回收时被优先考虑

G1 会跟踪老年代所有 incoming 引用,这样老年代 incoming 引用为0 的巨型对象就可以在新生代垃圾回收时处理掉

4.4.11) JDK 9 并发标记起始时间的调整

1.并发标记必须在堆空间占满前完成,否则退化为 FullGC

2.JDK 9 之前需要使用 -XX:InitiatingHeapOccupancyPercent

3.JDK 9 可以动态调整

???????? ◎-XX:InitiatingHeapOccupancyPercent 用来设置初始值

???????? ◎进行数据采样并动态调整

◎总会添加一个安全的空档空间

4.4.12) JDK 9 更高效的回收

250+增强 180+bug修复

Java Platform, Standard Edition HotSpot Virtual Machine Garbage Collection Tuning Guide, Release 12

?

5. 垃圾回收调优

需要提前学会知识:

1.? 掌握 GC 相关的 VM 参数,会基本的空间调整

如:"D:\Java\jdk1.8\bin\java"(jdk所安装的位置) -XX:+PrintFlagsFinal -version | findstr "GC"

2. ??掌握相关工具

3.? ?明确点:调优跟应用、环境有关,没有皆准的法则

5.1 调优领域

调优方向:1. 内存? 2. 锁竞争??? 3. cpu 占用??? 4. ?Io

综合调优才会有效

5.2 确定目标

1. 【低延迟】还是【高吞吐量】,选择合适的回收器

2. CMS,G1,ZGC(低延迟)(ZGC, jdk12出现)

3. ParallelGC (高吞吐量)

4. Zing

5.3 最快的 GC

答案:是不发生 GC

查看 FullGC 前后的内存占用,考虑下面几个问题:

  1. 数据是不是太多?(避免以下查太多)

resultSet = statement.executeQuery("select * from 大表")

  1. 数据表示是否太臃肿?

对象图(用什么查什么,不用全查)

对象大小 16 Integer 24 ?int 4(能用基本类型,不用包装类型)

  1. 是否存在内存泄漏?

static Map map = (长期放数据,使用不当)

可以使用软连接或者弱连接避免

◎第三方缓存实现(Redis,es等) -- 优先

5.4 新生代调优

新生代的特点:

◎所有的 new 操作的内存分配非常廉价

TLAB thread-local allocation bu?er(线程局部缓冲区)

◎死亡对象的回收代价是零

◎大部分对象用过即死

Minor GC 的时间远远低于 Full GC

新生代越大越好吗?

推荐25%--50%

新生代能容纳所有【并发量 * (请求-响应)】的数据

幸存区大到能保留【当前活跃对象+需要晋升对象】

晋升阈值配置得当,让长时间存活对象尽快晋升

-XX:MaxTenuringThreshold=threshold

-XX:+PrintTenuringDistribution

Desired survivor size 48286924 bytes, new threshold 10 (max 10)

  • age 1: 28992024 bytes, 28992024 total
  • age 2: 1366864 bytes, 30358888 total
  • age 3: 1425912 bytes, 31784800 total

5.5 老年代调优

以 CMS 为例:

CMS 的老年代内存越大越好

先尝试不做老年代调优,先尝试调优新生代

观察发生 Full GC 时老年代内存占用,将老年代内存预设调大 1/4 ~ 1/3

-XX:CMSInitiatingOccupancyFraction=percent

5.6 案例

案例1 Full GC 和 Minor GC频繁(1分钟上百次)

??? 优先加大新生代内存

案例2 请求高峰期发生 Full GC,单次暂停时间特别长 (CMS)

??? 看日志是哪个时间段耗时。如果重新标记耗时,可以在重新标记之前就回收新生代垃圾。

案例3 老年代充裕情况下,发生 Full GC (CMS jdk1.7)(jdk1.8引入了元空间,不会出现这个问题)

?

?

?

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章           查看所有文章
加:2022-01-24 10:41:48  更:2022-01-24 10:44:31 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:25:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码