类加载器
- 系统类加载器,加载jdk指定路径的jar包,String类等,运行时获取不到到该加载器
- 扩展类加载器,加载jdk扩展包,运行时能获取到加载器
- 应用类加载器(普通类默认加载器),可以自定义类加载器加载需要的类,比如字节码加密文件使用解密类加载器加载数据,运行时能获取到加载器
- 双亲委派机制,当使用类加载器加载类时,首先往上找到类加载器的父类加载器,直到没有父类加载器为止,父类加载器判断该类需不需要父类加载器加载,如不需要再往下委派,直到找到合适的类加载器就可以加载类,这种方式可以防止恶意篡改核心类,比如String类
- 类加载过程
运行时数据区
方法区
1.8之前叫永久代,1.8后叫元空间,存储类加载器加载的类信息、运行时常量池,1.8后移除静态变量、字符常量池至堆空间,gc很少回收,线程共享
堆
存储实例化对象的空间,具体分为新生代、老年代,空间占比1:2,新生代分为eden、s1、s2,空间占比8:1:1,线程共享,需要gc回收
虚拟机栈
java方法运行的数据区,每创建一个线程就创建一个栈,栈包含多个栈帧,每调用一次方法就生成一个栈帧并且入栈,完成后出栈,非线程共享,不需要gc回收
程序计数器
记录虚拟机栈代码运行的行数,驱动代码的运行,可以操作if判断、for循环、while循环、switch跳转、异常捕获等代码的跳转,在线程切换调度时可以准确的运行当前代码,非线程共享,不需要gc回收
本地方法栈
类型虚拟机方法栈,调用的是系统本地方法,与C或者C++打交道,如Thread线程的start调用,不需要gc,非线程共享
jvm直接内存
最大值等于堆最大值,超过上限是也会抛出OOM,在使用时少一次拷贝到jvm堆内存,效率高
JVM内存参数调节
- -Xms 堆初始值 1/64(<1G)
- -Xmx 堆最大值 1/4(<1G)
- -Xmn 年轻代 (eden+s0+s1),-Xmn150M
- -XX:NewRatio 年轻代和年老代的比例,默认-XX:NewRation=2 代表年轻代:年老代=1:2
- -XX:SurvivorRatio 设置幸存区和伊甸区比例,默认-XX:SurvivorRatio=8 ,伊甸区:幸存区0:幸存区1 = 8:1:11
- -XX:NewSize for 1.3/1.4/1.8,设置年轻代大小,-XX:NewSize=150m,优先级>NewRatio
- -XX:MaxNewSize for 1.3/1.4/1.8,设置年轻代大小的最大值
- -XX:PermSize 设置永久代值,1.8移除了该属性,-XX:PermSize=150m
- -XX:MaxPermSize 设置永久代值最大值,-XX:MaxPermSize=150m
- -XX:MetaspaceSize 设置元空间值 ,-XX:MetaspaceSize=2048m
- -XX:MaxMetaspaceSize 设置元空间最大值 ,-XX:MaxMetaspaceSize=2048m
- -XX:CompressdClassSpaceSize=2048m //压缩类空间大小
-Xss 栈空间设置单个线程栈大小,-Xss1m
-XX:+UseSerialGC 新生代SerialGC串行执行,老年代SerialGC Old GC
- -XX:+userParNewGC 新生代ParNew GC
- -XX:+userConMarkSweepGC 老年代cms 并发执行,自动激活userParNewGC ,低延迟,初始标记->并发标记->重新标记->并发清除,无法清除浮动垃圾,需要设置内存阈值提前垃圾回收,如在标记期间内存不足将采用SerialGC Old作为备选方案
- -XX:+CMSInitiatingOccupanyFraction 设置内存回收阈值,jdk5以前默认68(68%),jdk6即以上92
- -XX:+UserCMSCompactAtFullCollection 指定FullGC后对空间进行压缩整理,不能并发执行
- -XX:CMSFullGCsBeforeCompaction 设置在执行多少次Full GC后对内存空间进行压缩整理
-XX:ParallelCMSThreads 设置CMS的线程数量,cms默认启动线程数(core_count+3)/4
-XX:UseParallelGC 新生代UseParallelGC并行执行,吞吐量优先
- -XX:UseParalleOldGC 老年代UseParalle Old GC,与XX:UseParallelGC 相互激活
- -XX:ParallelGCThreads 设置UseParallelGC的回收线程数,核数小于8时设置核数,大于8时3+(count*5)/8
- -XX:MaxGCPauseMillis 设置stw停顿毫秒时间
- -XX:GCTimeRatio 1/(N+1)垃圾回收占总时间比例默认值99也就是1%
- -XX:+UseAdaptiveSizePolicy 设置UseParallelGC参数、堆空间自适应调整
-XX:+PrintCommandLineFlags 查看使用参数
JDK命令
jinfo -flag: jinfo -flag UseParallelGC 111(进程号),查看是否使用该参数
jps 查看java进程端口
jmap -histor 查看java对象内存大小排列
jstate -gc 查看gc实时回收状况
jstask 查看线程运行情况
垃圾回收算法
垃圾:没有被引用的对象,可以被gc回收的对象
分析对象垃圾算法
引用计数算法,对象记录被引用的次数,次数大于0不可回收,等于0可回收,优点效率高,缺点无法解决循环引用, var = A,A.var = B,B.var = A,当var = null时,A,B都不会被回收
可达性分析算法(gcroot搜索):栈、本地方法栈、静态变量、常量池、synchronized持有的对象都是属于被gcroot引用,非堆引用的对象,在分析其间为保证结果的一致性,所以会暂停用户线程的工作(stop the world)
对象被回收时gc线程会调用finalization方法执行对象回收前的最后操作,不建议使用可能影响gc回收的效率,finalization最多执行一次
对象三种状态引用状态状态,可复活状态、不可复活状态
分代垃圾回收器 ,cms老年代垃圾回收器,使用标记清除算法
增量收集算法,用户线程和gc线程交替运行,线程需要上下文切换,造成系统吞吐量下降
分区算法,把堆空间划分更小的块,根据gc回收的时间来决定回收的区块数量
垃圾回收器
时间线
Serial GC - Serial Old GC:1999年 jdk1.31串行方式
ParNew GC:Serial 多线程版
Parallel Scavenge GC - Parallel Old GC:2002.02.26 jdk1.4.2
Concurrent Mark Sweep(CMS):2002.02.26 jdk1.4.2
G1:2012 jdk1.7u4 新生代和老年代 jdk9代替CMS
Epsilon(No-Op):2018.09 jdk11
ZGC:jdk11
Shenandoah GC:2019.3 jdk12 增强G1
串行回收器:Serial、Serial Old
并行回收器:ParNew、Parallel Scavenge、Parallel Old
并发回收器:CMS、G1
新生代回收器:Serial、Paraller Scavenge、ParNew
老年代:Serial Old、Parallel Old、CMS
整体收集器:G1

