JVM学习路线
堆的核心概述
一个进程一个堆,一个进程有多个线程,多个线程共享一个堆,
一个方法区。一个线程有自己的PC,本地方法栈,虚拟机栈
在方法结束后,队中的对象不会马上被移除,仅仅在垃圾手机的时候才会被移除。
堆,是GC执行垃圾回收的重点区域。
内存细分
查看命令
jvisualvm
jdk8 中内存结构的一个变化是永久区Perm变成元空间Meta
设置堆内存大小与OOM
-X 是jvm的运行参数
ms memory start
-Xms 用来设置对空间(年轻代+老年代)的最大内存大小
查看设置参数
1、jps jstat -gc 进程id
2、-XX:+PrintGCDeatils
在开发中建议把初始内存和最大内存设置为一样的值
(扩容和降容会造成系统的压力)
年轻代与老年代
新生代中Eden : s0 : s1 = 8:1:1
常见的JVM命令
图解对象分配过程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xosGrX5y-1657780172414)(D:\Learn\java\JVM\堆.assets\image-20220611151506548.png)]
总结
- 针对幸存者s0,s1区:复制之后有交换,谁空谁是to
- 关于垃圾回收:频繁在新生区收集,很少在养老去收集,几乎不在永久区/元空间收集
常见的调优工具
Minor GC、Major GC、Full GC
分别是新生代GC,老年代GC(MGC,FGC在某种意义上可以说是一样的)
STW :可以理解为暂停制造垃圾
调优的目的
减少GC,提高性能
堆空间分代思想
内存分配策略
为对象分配内存:Tlab
在堆中为每个线程分配一个独有的内存空间,叫做TLAB
![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p6jpJ0Hh-1657780172416)(D:\Learn\java\JVM\堆.assets\image-20220611212422684.png)\]](https://img-blog.csdnimg.cn/9657a96073f24d3195bcbac544d9fd27.png)
分配过程
小结堆空间的参数设置
堆是分配对象存储的唯一选择吗
逃逸
方法内部的变量会实例如果在方法外也被使用到,就是逃逸了,就不能使用栈赖存储而只能使用堆存储了。否则可以用栈赖储存,减轻堆的负担,进而达到了一个性能调优的目的!
避免逃逸的一个方法
如何快速的分析是否发生逃逸分析,就看new的对象实体是否可以被外部调用
结论:开发中能使用局部变量的,就不要使用在方法外定义。
栈上分配
开启逃逸分析后,如果程序中有很多代码端不会发生逃逸,则可以明显提高程序的性能!
:+DoEscapeAnalysis
同步省略
分离对象或标量替换
将聚合量(k,v) 分解成标量
EliminateAllocations
使用和不使用的效果对比