JVM相关问题
1、JVM/JRE/JDK
JVM(Java Virtual Machine),java虚拟机,屏蔽操作系统细节,为java程序提供字节码指令集、寄存器、栈、垃圾回收堆和一个存储方法域。是JRE的一部分
JRE(Java Runtime Environment),也就是java平台。所有的java程序都要在JRE环境下才能运行。包含JVM。
JDK(Java Development Kit),是开发者用来编译、调试程序用的开发包。JDK也是JAVA程序,在JRE上运行。
2、堆内存
新生代("堆(heap)"内存)(eden:from:to=8:1:1):新对象区
老年代("堆(heap)"内存):老对象区
持久代(“非堆(non-heap)”内存):java类信息区
新生代:老年代=1:2
3、GC
查看gc情况的方法: jstat -gc 152778 1000 (指定pid、时间间隔,连续输出GC情况)
三种算法:
- 复制算法:存活对象移入另一片区域(1、存活对象少的时候比较好;2、必须留一片空白区域用来复制)
- 标记-清除算法:不存活对象原地丢弃(快,导致内存碎片)
- 标记-整理算法:不存活对象原地丢弃,之后将存活对象移入另一片区域(成本最高)
三者都需要"标记"过程来识别存活对象,就是从一棵树的根节点自上向下遍历,遍历到的存活,到不了的就不存活,例如一个对象引用了别人,但是没人引用它,则GC时会被清除
新生代回收:Minor GC,复制算法
触发时机:新对象在eden中出生(超过一定大小直接接入老年代),eden区空间不够存放新对象时执行
Minor GC步骤:
- 查看eden区,仍存活的对象被移入存活区to,年龄设为1;
- 查看存活区from,年龄达到一定水平(MaxTenuringThreshold,默认15)的对象移入老年代,年龄没达标的移入存活区to,年龄+1,如果此时to已经满了,就进入老年代。
- 然后调换from和to的名字,回到eden、to为空,from有部分对象的状态。
老年代回收:Full GC(Major GC),标记-整理算法,时间为Minor GC的约10倍
触发时机:1、老生代空间用完(持久代空间用完会引发持久代的Full GC);2、System.gc()被显式调用
内存用尽且GC无法回收到空间就会报java.lang.OutOfMemoryError错误
GC优化
主要目的是减少老年代Full GC,减少STW
主要优化手段:
- 系统侧:调大JVM堆内存(大小一定时短寿对象多加大新生代,长寿对象多加大老年代)、最大最小堆内存相同(减少内存抖动造成的STW)、选择合适的GC收集器;
- 应用侧:少生成对象,使用常驻对象而不是频繁生成销毁对象
-Xms 初始化(最小值)堆内存 –Xmx 最大堆内存,一般两个设置是一样的,如果不一样,当Heap不够用,会发生内存抖动。一般都尽量调大这两个参数,并且两个大小一样。
GC 命令行选项 | 描述 |
-Xms | 设置Java堆大小的初始值/最小值。例如:-Xms512m (请注意这里没有”=”). |
-Xmx | 设置Java堆大小的最大值 |
-Xmn | 设置年轻代对空间的初始值,最小值和最大值。请注意,年老代堆空间大小是依赖于年轻代堆空间大小的 |
-XX:PermSize=<n>[g|m|k] | 设置持久代堆空间的初始值和最小值 |
-XX:MaxPermSize=<n>[g|m|k] | 设置持久代堆空间的最大值 |
-Xss | 设置每个线程堆栈的大小。一般情况下256K即可。影响jvm中并发线程数大小。 |
GC收集器
新生代收集器:
- Serial (-XX:+UseSerialGC)单线程 复制
- ParNew(-XX:+UseParNewGC)多线程版 复制
- ParallelScavenge(-XX:+UseParallelGC)多线程优化版 复制
- G1 收集器
老年代收集器:
- SerialOld(-XX:+UseSerialOldGC)单线程老年代版 标记-整理
- ParallelOld(-XX:+UseParallelOldGC)多线程版老年代版 标记-整理
- CMS(-XX:+UseConcMarkSweepGC)标记-清除(注意此处与其他的不同)
- G1 收集器
G1:新老年代通用,有CMS的优点且没有内存碎片
CMS:缺点:1、产生内存碎片;2、对cpu、内存要求高。优点:相对于标记-整理的一次长时间STW(全局暂停),CMS的标记-清除的STW分为两次且较短,有利于提高响应速度
在注重吞吐量与CPU数量大于1的情况下,优先考虑ParallelScavenge + ParalleloOld。
在要求服务器响应速度高的情况下,使用CMS。
相关文章:https://www.cnblogs.com/jiling/p/8527050.html
4、JVM架构
主要组件包括三块(右下角是对接本地部分):类加载子系统、运行时数据区、执行引擎
详细介绍:
https://blog.****.net/aijiudu/article/details/72991993
https://www.cnblogs.com/dooor/p/5289994.html
https://baijiahao.baidu.com/s?id=1571097398171757&wfr=spider&for=pc
https://blog.****.net/javazejian/article/details/73413292