不对之处还望指正。
垃圾回收
1. 如何判断对象是垃圾对象?
引用计数法
在对象中添加一个引用计数器,当有地方引用这个对象的时候,引用计数器的值+1,当引用失效时,则值-1. 此方式不能解决循环引用的问题。
- 验证
添加gc日志,_005GC.java -verbose:gc -XX:+PrintGCDetails
发现hotspot不是使用此法。
可达性分析法
对象根root不可达。
- 可以作为GCroots的对象
- 虚拟机栈
- 方法区的类属性所引用的对象
- 方法区中常量所引用的对象
- 本地方法栈中引用的对象。
2.如何回收?
回收策略
标记清除算法
通过可达性算法,标记出垃圾对象,将存活对象复制到S区,标记区域清空。
- 效率问题
需要两步,先标记,后清除。
- 空间问题
空间碎片严重,空间不连续,创建大对象时,需要检索到合适空间。
复制算法(新生代)
- 堆
- 新生代
- Eden 伊甸园
- Survivor 存活区
- Tenured Gen
- 老年代
- 新生代
- 方法区
- 栈 本地方法栈 程序计数器
标记整理(老年代)
先标记要回收的垃圾对象,将需要回收的垃圾对象向一端移动,然后统一回收。基本是划分出一个区域,如果里面有不需要回收的,移动出去,需要回收的移进来,完毕后,回收该区域。
分代收集算法
根据分代,选择不同的算法,即复制算法和标记整理算法的结合。
垃圾回收器
Serial
Parnew
- 多线程收集器,可与CMS结合使用
Parallel Scavenge(新生代)
- 复制算法
- 多线程
- 达到可控制吞吐量
- -XX:MaxGCPauserMillis 垃圾收集器停顿时间
不是越小越好,越小可能回收的频率增高。比如原来10ms 设置为1 则会收集10次。
- -XX:GCTimeRatio 吞吐量大小
吞吐量:CPU用于运行用户代码的时间与CPU消耗总时间的比值。
吞吐量=(执行用户代码时间)/(执行用户代码时间+垃圾回收占用时间)
cms(Concurrent Mark Sweep)
工作过程
- 初始标记
- 并发标记
- 重新标记
- 并发清理
优点
- 并发收集
- 低停顿
缺点
- 占用大量cpu资源
- 无法处理浮动垃圾
- 出现ConcurrentModeFailure
- 空间碎片
- cms收集老年代,ParNew收集新生代。
G1
历史
2004年已经提出
优势
- 并行与并发。可以真正的不停止应用来收集垃圾。
- 分代收集
- 空间整合
- 可预测的停顿
步骤
- 初始标记
- 并发标记
- 最终标记
- 筛选标记
与CMS比较
两者占用cpu资源都比较高,都是低停顿。而G1是划分区域(Region),即一块区域一块区域的,而传统的是整体划分了几个区域。
3.何时回收?
内存分配
内存分配策略
优先分配到Eden
优先分配到eden,如果容量不满足则触发一次mingc,
大对象直接分配到老年代
判定条件是eden区的一半,>=则晋升老年代 可以通过-XX:PretenureSizeThreshold=8M来设定阈值。
长期存活对象分配到老年代
可以通过-XX:MaxTenuringThreshold=15来设置,默认15
空间分配担保
-XX:HandlePromotionFailure
为了更好的适应不同程序的内存状况,对象年龄不是必须到达阈值才会进入老年代。 只要老年代的连续空间大于新生代对象总大小或者历次晋升的平均大小就会进行Minor GC,否则将进行Full GC。
动态对象年龄判断
如果在Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代
虚拟机工具
jdk提供了很多工具,默认在bin目录中,基本都是依赖tools.jar文件。
jps
Java进程状态 类似linux的ps命令
- 本地虚拟机唯一Id lvmid local virtual machine id
- m 运行时传入主类的参数 入口传递的argument
- v虚拟机参数
- l 运行的主类全名或者包名
C:\Users\zdwljs>jps 2256 7376 RemoteMavenServer 12584 Launcher 4120 Jps 9644
C:\Users\zdwljs>jps -l 12176 sun.tools.jps.Jps 2256 7376 org.jetbrains.idea.maven.server.RemoteMavenServer 12584 org.jetbrains.jps.cmdline.Launcher 9644
C:\Users\zdwljs>jps -help
usage: jps [-help]
jps [-q] [-mlvV] [
Jstat
类装载,内存,垃圾收集,jit编译信息。 官方文档
C:\Users\zdwljs>jstat -help Usage: jstat -help|-options jstat -
Definitions:
C:\Users\zdwljs>jstat -gcutil 7376 S0 S1 E O M CCS YGC YGCT FGC FGCT GCT 0.00 0.00 4.44 2.55 96.40 91.49 73 0.206 72 2.594 2.799
- 每隔1s执行一次,共监控10次。
C:\Users\zdwljs>jstat -gcutil 7376 1000 10 S0 S1 E O M CCS YGC YGCT FGC FGCT GCT 0.00 0.00 5.69 2.55 96.40 91.49 73 0.206 72 2.594 2.799 0.00 0.00 5.69 2.55 96.40 91.49 73 0.206 72 2.594 2.799 0.00 0.00 5.69 2.55 96.40 91.49 73 0.206 72 2.594 2.799 0.00 0.00 5.69 2.55 96.40 91.49 73 0.206 72 2.594 2.799 0.00 0.00 5.69 2.55 96.40 91.49 73 0.206 72 2.594 2.799 0.00 0.00 5.69 2.55 96.40 91.49 73 0.206 72 2.594 2.799 0.00 0.00 5.69 2.55 96.40 91.49 73 0.206 72 2.594 2.799 0.00 0.00 5.69 2.55 96.40 91.49 73 0.206 72 2.594 2.799 0.00 0.00 5.69 2.55 96.40 91.49 73 0.206 72 2.594 2.799 0.00 0.00 5.69 2.55 96.40 91.49 73 0.206 72 2.594 2.799
Garbage-collected heap statistics.
S0C: Current survivor space 0 capacity (kB).
S1C: Current survivor space 1 capacity (kB).
S0U: Survivor space 0 utilization (kB).
S1U: Survivor space 1 utilization (kB).
EC: Current eden space capacity (kB).
EU: Eden space utilization (kB).
OC: Current old space capacity (kB).
OU: Old space utilization (kB).
MC: Metaspace capacity (kB).
MU: Metacspace utilization (kB).
CCSC: Compressed class space capacity (kB).
CCSU: Compressed class space used (kB).
YGC: Number of young generation garbage collection events.
YGCT: Young generation garbage collection time.
FGC: Number of full GC events.
FGCT: Full garbage collection time.
GCT: Total garbage collection time.
Jinfo
实时查看和调整参数
C:\Users\zdwljs>jinfo -flag UseConcMarkSweepGC 2256 -XX:+UseConcMarkSweepGC
C:\Users\zdwljs>jinfo -help
Usage:
jinfo [option]
where
Jmap
打印内存或者堆空间细节。 官方文档
C:\Users\zdwljs>jmap -help
Usage:
jmap [option]
where
C:\Users\zdwljs>jmap -dump:format=b,file=d:\work\jvm\ricky.hprof 2256 Dumping heap to D:\work\jvm\ricky.hprof ... Heap dump file created
利用上述方式进行快照生成,使用mat进行分析。
- 存活实例
C:\Users\zdwljs>jmap -histo:live 2256 | more
num #instances #bytes class name
1: 60579 52974648 [B 2: 305141 31563088 [C 3: 32929 19770080 [I 4: 302030 7248720 java.lang.String 5: 61139 6692992 java.lang.Class 6: 90152 6592144 [Ljava.lang.Object; 7: 81443 2606176 java.util.HashMap$Node 8: 48852 1563264 com.intellij.util.text.ByteArrayCharSequence 9: 47477 1519264 org.jdom.Attribute 10: 46998 1503936 java.util.concurrent.ConcurrentHashMap$Node 11: 8922 1496016 [J 12: 9889 1468048 [Ljava.util.HashMap$Node; 13: 34702 1388080 java.util.LinkedHashMap$Entry 14: 38597 1235104 com.intellij.util.containers.IntObjectLinkedMap$MapEntry 15: 69142 1106272 java.lang.Integer 16: 23246 929840 org.jdom.Element 17: 35141 843384 com.intellij.util.SmartList 18: 19850 794000 com.intellij.util.containers.hash.LinkedHashMap$Entry 19: 18059 770664 [Lorg.jdom.Attribute; 20: 23541 753312 org.jdom.ContentList 21: 23246 743872 org.jdom.AttributeList 22: 18580 743200 java.lang.ref.SoftReference 23: 29987 719688 org.jdom.Text 24: 6691 588808 java.lang.reflect.Method 25: 18193 582176 java.util.Hashtable$Entry 26: 479 517184 [F 27: 8637 483672 java.lang.invoke.MemberName 28: 600 468776 [Ljava.util.concurrent.ConcurrentHashMap$Node; 29: 11516 460640 com.intellij.openapi.extensions.impl.ExtensionComponentAdapter 30: 9436 452928 com.intellij.util.pico.CachingConstructorInjectionComponentAdapter 31: 6834 451984 [Lorg.jdom.Content; 32: 6935 443840 java.net.URL 33: 17241 413784 java.util.ArrayList
jhat
JVM Heap Analysis Tool jvm堆分析工具
C:\Users\zdwljs>jhat -help
Usage: jhat [-stack
-J<flag> Pass <flag> directly to the runtime system. For
example, -J-mx512m to use a maximum heap size of 512MB
-stack false: Turn off tracking object allocation call stack.
-refs false: Turn off tracking of references to objects
-port <port>: Set the port for the HTTP server. Defaults to 7000
-exclude <file>: Specify a file that lists data members that should
be excluded from the reachableFrom query.
-baseline <file>: Specify a baseline object dump. Objects in
both heap dumps with the same ID and same class will
be marked as not being "new".
-debug <int>: Set debug level.
0: No debug output
1: Debug hprof file parsing
2: Debug hprof file parsing, no server
-version Report version number
-h|-help Print this help and exit
<file> The file to read
For a dump file that contains multiple heap dumps,
you may specify which dump in the file
by appending "#
All boolean options default to "true"
- 示例
指定快照地址,以及本地http端口
C:\Users\zdwljs>jhat -port 1234 d:\work\jvm\ricky.hprof Reading from d:\work\jvm\ricky.hprof... Dump file created Mon Apr 02 13:39:22 CST 2018 Snapshot read, resolving... Resolving 6152505 objects... Chasing references, expect 1230 dots.............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................. Eliminating duplicate references.............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................. Snapshot resolved. Started HTTP server on port 1234 Server is ready.
jsack
打印一个Java线程栈追踪信息,官方文档
C:\Users\zdwljs>jstack -help
Usage:
jstack [-l]
Options:
-F to force a thread dump. Use when jstack
- 实例
C:\Users\zdwljs>jstack -l 2256 2018-04-02 14:10:41 Full thread dump OpenJDK 64-Bit Server VM (25.152-b15 mixed mode):
"ApplicationImpl pooled thread 2513" #4852 daemon prio=4 os_prio=-1 tid=0x000000005907a000 nid=0x3178 waiting on condition [0x000000007e48f000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x00000000e0f37c70> (a java.util.concurrent.SynchronousQueue$TransferStack) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:458) at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:362) at java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:924) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers: - None