jvm(五)jvm终极篇


在这里插入图片描述

垃圾收集发生的时机

(1)当Eden区或者S区不够用了
(2)老年代空间不够用了
(3)方法区空间不够用了
(4)System.gc()

GC日志文件分析

配置审查各行日志文件
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:gc.log
启动项目,生成日志文件,默认使用paraller GC收集器

paraller gc日志【吞吐量优先】

在这里插入图片描述

CMS日志文件【停顿时间优先】

-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+UseConcMarkSweepGC -Xloggc:cms.log

G1日志文件【停顿时间优先】

-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+UseG1GC -Xloggc:g1.log

GC 日志文件分析工具

gceasy
在这里插入图片描述

GCViewer
在这里插入图片描述

G1调优

是否选择G1收集器:
(1)50%以上的堆被存活对象占用
(2)对象分配和晋升的速度变化非常大
(3)垃圾回收时间比较长

(1)使用G1GC垃圾收集器: -XX:+UseG1GC

修改配置参数,获取到gc日志,使用GCViewer分析吞吐量和响应时间

在这里插入图片描述
(2)调整内存大小再获取gc日志分析

-XX:MetaspaceSize=100M
-Xms300M
-Xmx300M

比如设置堆内存的大小,获取到gc日志,使用GCViewer分析吞吐量和响应时间

在这里插入图片描述

(3)调整最大停顿时间

-XX:MaxGCPauseMillis=20 设置最大GC停顿时间指标
比如设置最大停顿时间,获取到gc日志,使用GCViewer分析吞吐量和响应时间

在这里插入图片描述
(4)启动并发GC时堆内存占用百分比

-XX:InitiatingHeapOccupancyPercent=45 G1用它来触发并发GC周期,基于整个堆的使用率,而不只是某一代内存的使用比例。值为 0 则表示“一直执行GC循环)'. 默认值为 45 (例如, 全部的 45% 或者使用了45%).

比如设置该百分比参数,获取到gc日志,使用GCViewer分析吞吐量和响应时间

Throughput       Min Pause        Max Pause      Avg Pause      GC count
98.11%            0.00406s        0.00532s        0.00469s          12

调优指南

1、不要手动设置新生代和老年代的大小,只要设置整个堆的大小
2、不断调优暂停时间目标
3、使用-XX:ConcGCThreads=n来增加标记线程的数量
4、MixedGC调优
5、适当增加堆内存大小

高并发与堆内存

在这里插入图片描述

jvm性能优化指南

在这里插入图片描述

常见问题思考

(1)内存泄漏与内存溢出的区别

内存泄漏:对象无法得到及时的回收,持续占用内存空间,从而造成内存空间的浪费。
内存溢出:内存泄漏到一定的程度就会导致内存溢出,但是内存溢出也有可能是大对象导致的。

(2)young gc会有stw吗?

不管什么 GC,都会有 stop-the-world,只是发生时间的长短。

(3)major gc和full gc的区别

major gc指的是老年代的gc,而full gc等于young+old+metaspace的gc。

(4)G1与CMS的区别是什么

CMS 用于老年代的回收,而 G1 用于新生代和老年代的回收。
G1 使用了 Region 方式对堆内存进行了划分,且基于标记整理算法实现,整体减少了垃圾碎片的产生。

(5)什么是直接内存

直接内存是在java堆外的、直接向系统申请的内存空间。通常访问直接内存的速度会优于Java堆。因此出于性能的考
虑,读写频繁的场合可能会考虑使用直接内存。

(6)不可达的对象一定要被回收吗?

即使在可达性分析法中不可达的对象,也并非是“非死不可”的,这时候它们暂时处于“缓刑阶段”,要真正宣告一个对
象死亡,至少要经历两次标记过程;可达性分析法中不可达的对象被第一次标记并且进行一次筛选,筛选的条件是此
对象是否有必要执行 finalize 方法。当对象没有覆盖 finalize 方法,或 finalize 方法已经被虚拟机调用过时,虚拟机
将这两种情况视为没有必要执行。
被判定为需要执行的对象将会被放在一个队列中进行第二次标记,除非这个对象与引用链上的任何一个对象建立关
联,否则就会被真的回收。

(7)方法区中的无用类回收

方法区主要回收的是无用的类,那么如何判断一个类是无用的类的呢?
判定一个常量是否是“废弃常量”比较简单,而要判定一个类是否是“无用的类”的条件则相对苛刻许多。类需要同时满
足下面 3 个条件才能算是 “无用的类” :
该类所有的实例都已经被回收,也就是 Java 堆中不存在该类的任何实例。
加载该类的 ClassLoader 已经被回收。
该类对应的 java.lang.Class 对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。
虚拟机可以对满足上述 3 个条件的无用类进行回收,这里说的仅仅是“可以”,而并不是和对象一样不使用了就会必然
被回收。

(8)不同的引用

JDK1.2以后,Java对引用进行了扩充:强引用、软引用、弱引用和虚引用	
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值