GC日志输出
不同的垃圾回收器输出的日志格式不同,但是Jvm对格式进行了统一表示
StopWorldDemo类
该代码引用了周明耀的《深入理解 JVM & G1 GC》
package Gc;
import java.util.HashMap;
public class StopWorldDemo {
public static class MyThread extends Thread {
HashMap map = new HashMap();
public void run() {
try {
while (true) {
if (map.size() * 512 / 1024 / 1024 >= 400) {
map.clear();
System.out.println("clean map");
}
byte[] b1;
for (int i = 0; i < 100; i++) {
b1 = new byte[512];
map.put(System.nanoTime(), b1);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static class PrintThread extends Thread {
public final long startTime = System.currentTimeMillis();
public void run() {
try {
while (true) {
long t = System.currentTimeMillis() - startTime;
System.out.println(t / 1000 + "." + t%1000);
Thread.sleep(1000);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new MyThread().start();
new PrintThread().start();
}
}
PS F:\idea\leet\src\Gc> javac StopWorldDemo.java
JVM加载类过程:加载、验证、准备、解析、初始化
进对应目录把java转换为class
执行相关命令
F:\idea\leet\src> java -Xmx512M -Xms512M -XX:+PrintGCDetails Gc.StopWorldDemo
输出:
说明
Jvm的GC区分partialGc he Full GC
Partial GC(局部 GC): 并不收集整个 GC 堆的模式 - Young GC: 只收集young gen的GC,Young GC还有种说法就叫做 "Minor GC" - Old GC: 只收集old gen的GC。只有垃圾收集器CMS的concurrent collection 是这个模式 - Mixed GC: 收集整个young gen 以及部分old gen的GC。只有垃圾收集器 G1有这个模式
Full GC 就是收集整个堆,包括新生代,老年代,永久代(在JDK 1.8及以后,永久代会被移除,换为metaspace(元空间))等收集所有部分的模式。
针对不同的垃圾收集器,Full GC的触发条件可能不都一样。按HotSpot VM的serial GC的实现来看,触发条件是:
1.当准备要触发一次 young GC时,如果发现统计数据说之前 young GC的平均晋升大小比目前的 old gen剩余的空间大,则不会触发young GC而是转为触发 full GC (因为HotSpot VM的GC里,除了垃圾回收器 CMS的concurrent collection 之外,其他能收集old gen的GC都会同时收集整个GC堆,包括young gen,所以不需要事先准备一次单独的young GC)
2.如果有永久代(perm gen),要在永久代分配空间但已经没有足够空间时,也要触发一次 full GC
3.执行System.gc(),heap dump带GC,其默认都是触发 full GC.
默认GC Serial
Partial GC(GC)
[GC (Allocation Failure) [DefNew: 139776K->17472K(157248K), 0.1721014 secs] 139776K->124044K(506816K), 0.1725615 secs] [Times: user=0.09 sys=0.08, real=0.17 secs]
-
GC:清理新生代
-
Allocation Failure:表示新生代分配失败
-
注意:此处使用Serial收集器
-
Serial收集器中的新生代名为“Default New Generation”,所以显示的是“DefNew”
-
ParNew收集器,新生代名称就会变为“ParNew”,意为“Parallel New Generation”
-
Parallel Scavenge收集器,那它配套的新生代称为“PSYoungGen”,
-
老年代和永久代同理,名称也是由收集器决定的
-
-
[DefNew: 139776K->17472K(157248K), 0.1721014 secs]新生代:垃圾清除前大小139776K -> 垃圾清除后大小17472K(总大小:157248K)
-
139776K->124044K(506816K):139776K(堆空间垃圾清除前大小) -> 124044K(堆空间垃圾清除后大小)(506816K堆空间总大小)
Full GC
[Full GC (Allocation Failure) [Tenured: 349567K->52367K(349568K), 0.1327730 secs] 506815K->52367K(506816K), [Metaspace: 1693K->1693K(4480K)], 0.1335487 secs] [Times: user=0.13 sys=0.00, real=0.13 secs]
-
[Tenured: 349567K->52367K(349568K), 0.1327730 secs] 506815K->52367K(506816K):老年代的GC
-
[Metaspace: 1693K->1693K(4480K)], 0.1335487 secs]元空间GC
-
user,用户线程花费的时间
-
sys,系统线程花费的时间
-
real,从GC开始到结束的时钟时间(开始时间与结束时间的差值)
使用Parallel Scavenge+Parallel Old
GC
[GC (Allocation Failure) [PSYoungGen: 131072K->21744K(152832K)] 131072K->119944K(502528K), 0.0535634 secs] [Times: user=0.19 sys=0.14, real=0.05 secs]
-
GC:清理新生代
-
Allocation Failure:新生代分配对象失败
-
PSYoungGen:代表使用Parallel Scavenge垃圾收集器的新生代
-
[PSYoungGen: 131072K->21744K(152832K)]:新生代:垃圾清除前大小131072K-> 垃圾清除后大小21744K(总大小:152832K)
-
131072K->119944K(502528K):131072K(堆空间垃圾清除前大小) -> 119944K(堆空间垃圾清除后大小)(502528K堆空间总大小)
FullGC
[Full GC (Ergonomics) [PSYoungGen: 131072K->0K(152832K)] [ParOldGen: 349466K->20454K(349696K)] 480538K->20454K(502528K), [Metaspace: 1693K->1693K(4480K)], 0.0236842 secs] [Times: user=0.09 sys=0.00, real=0.02 secs]
-
Full GC :收集整个堆,包括young gen、old gen、perm gen(如果存在的话)等所有部分的模式。
-
[PSYoungGen: 131072K->0K(152832K)]:新生代:垃圾清除前大小131072K-> 垃圾清除后大小0K(总大小:152832K)
-
ParOldGen:使用Parallel old垃圾收集器的老生代
-
[ParOldGen: 349466K->20454K(349696K)] 480538K->20454K(502528K):老年代:垃圾清除前大小349466K->垃圾清除后大小20454K(总大小349696K)
-
user,用户线程花费的时间
-
sys,系统线程花费的时间
-
real,从GC开始到结束的时钟时间(开始时间与结束时间的差值)
常见GC相关的JVM命令
配置堆区参数
-
-Xms:Java虚拟机堆区内存初始内存分配的大小,按照实际情况进行分配(一般为操作系统可用内存的1/64大小)
-
-Xmx:Java虚拟机堆区内存可被分配的最大上限(一般为操作系统可用内存的1/4大小)
注意:①一般-Xms、-Xmx两个参数会配置相同的值(优点:能够在Java垃圾回收机制清理完堆区后不需要重新分隔计算堆区的大小而浪费资源)
-
-XX:newSize:新生代初始化内存的大小(注意:该值需要小于-Xms的值)
-
-XX:MaxnewSize:新生代可被分配的内存的最大上限(注意:该值需要小于-Xmx的值)
-
-Xmn:对-XX:newSize、-XX:MaxnewSize两个参数同时进行配置(注意:JDK1.4之后才有该参数)
非堆参数区:
-
-XX:PermSize:非堆区初始化内存分配大小
-
-XX:MaxPermSize:非堆区分配的内存的最大上限
其他
-
-XX:+PrintGCDetails :打印GC的日志细节
-
-XX:+PrintCommandLineFlags 打印HotSpotVM 采用的自动优化参数
设置垃圾收集器
-
-XX:+UseSerialGC,虚拟机运行在Client模式下的默认值,Serial+Serial Old。
-
-XX:+UseParNewGC,ParNew+Serial Old,在JDK1.8被废弃,在JDK1.7还可以使用。
-
-XX:+UseConcMarkSweepGC,ParNew+CMS+Serial Old。
-
-XX:+UseParallelGC,虚拟机运行在Server模式下的默认值,Parallel Scavenge+Serial Old(PS Mark Sweep)。
-
-XX:+UseParallelOldGC,Parallel Scavenge+Parallel Old。
-
-XX:+UseG1GC,G1+G1。
常见错误
Java————错误:找不到或无法加载主类
-
可能编译的时候带后缀.class,把后缀去掉
-
可能java文件带了package包,但是还在文件所在行运行,返回包的前一个目录即可(返回到包的顶级目录)
执行命令: