代码:
public class GcTest01 {
private static final int _1MB = 1024* 1024;
/**
-Xms30M
-Xmx30M
-XX:+PrintGCDetails
-XX:+PrintHeapAtGC
-XX:+PrintGCDetails 输出gc的详细日志
-XX:+PrintHeapAtGC 打印出触发gc之前 之后的日志
*/
public static void main(String[] args) throws InterruptedException {
byte[] allocation,allocation2,allocation3,allocation4;
allocation = new byte[2*_1MB];
System.out.println("--------创建2M后--------");
allocation2 = new byte[2*_1MB];
System.out.println("--------创建2M后--------");
allocation3 = new byte[2*_1MB];
System.out.println("--------创建2M后--------");
}
}
"C:\Program Files\Java\jdk1.8.0_241\bin\java.exe" -Xms30M -Xmx30M -XX:+PrintGCDetails -XX:+PrintHeapAtGC "-javaagent:D:\IntelliJ IDEA 2020.1\lib\idea_rt.jar=4495:D:\IntelliJ IDEA 2020.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_241\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_241\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_241\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_241\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_241\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_241\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_241\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_241\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_241\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_241\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_241\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_241\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_241\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_241\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_241\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_241\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_241\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_241\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_241\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_241\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_241\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_241\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_241\jre\lib\rt.jar;E:\develop\jvm\jvm-study\target\test-classes;E:\develop\jvm\jvm-study\target\classes;D:\env\maven\repo\org\springframework\boot\spring-boot-starter-web\2.3.1.RELEASE\spring-boot-starter-web-2.3.1.RELEASE.jar;D:\env\maven\repo\org\springframework\boot\spring-boot-starter\2.3.1.RELEASE\spring-boot-starter-2.3.1.RELEASE.jar;D:\env\maven\repo\org\springframework\boot\spring-boot\2.3.1.RELEASE\spring-boot-2.3.1.RELEASE.jar;D:\env\maven\repo\org\springframework\boot\spring-boot-autoconfigure\2.3.1.RELEASE\spring-boot-autoconfigure-2.3.1.RELEASE.jar;D:\env\maven\repo\org\springframework\boot\spring-boot-starter-logging\2.3.1.RELEASE\spring-boot-starter-logging-2.3.1.RELEASE.jar;D:\env\maven\repo\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;D:\env\maven\repo\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;D:\env\maven\repo\org\apache\logging\log4j\log4j-to-slf4j\2.13.3\log4j-to-slf4j-2.13.3.jar;D:\env\maven\repo\org\apache\logging\log4j\log4j-api\2.13.3\log4j-api-2.13.3.jar;D:\env\maven\repo\org\slf4j\jul-to-slf4j\1.7.30\jul-to-slf4j-1.7.30.jar;D:\env\maven\repo\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;D:\env\maven\repo\org\yaml\snakeyaml\1.26\snakeyaml-1.26.jar;D:\env\maven\repo\org\springframework\boot\spring-boot-starter-json\2.3.1.RELEASE\spring-boot-starter-json-2.3.1.RELEASE.jar;D:\env\maven\repo\com\fasterxml\jackson\core\jackson-databind\2.11.0\jackson-databind-2.11.0.jar;D:\env\maven\repo\com\fasterxml\jackson\core\jackson-core\2.11.0\jackson-core-2.11.0.jar;D:\env\maven\repo\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.11.0\jackson-datatype-jdk8-2.11.0.jar;D:\env\maven\repo\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.11.0\jackson-datatype-jsr310-2.11.0.jar;D:\env\maven\repo\com\fasterxml\jackson\module\jackson-module-parameter-names\2.11.0\jackson-module-parameter-names-2.11.0.jar;D:\env\maven\repo\org\springframework\boot\spring-boot-starter-tomcat\2.3.1.RELEASE\spring-boot-starter-tomcat-2.3.1.RELEASE.jar;D:\env\maven\repo\org\apache\tomcat\embed\tomcat-embed-core\9.0.36\tomcat-embed-core-9.0.36.jar;D:\env\maven\repo\org\glassfish\jakarta.el\3.0.3\jakarta.el-3.0.3.jar;D:\env\maven\repo\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.36\tomcat-embed-websocket-9.0.36.jar;D:\env\maven\repo\org\springframework\spring-web\5.2.7.RELEASE\spring-web-5.2.7.RELEASE.jar;D:\env\maven\repo\org\springframework\spring-beans\5.2.7.RELEASE\spring-beans-5.2.7.RELEASE.jar;D:\env\maven\repo\org\springframework\spring-webmvc\5.2.7.RELEASE\spring-webmvc-5.2.7.RELEASE.jar;D:\env\maven\repo\org\springframework\spring-aop\5.2.7.RELEASE\spring-aop-5.2.7.RELEASE.jar;D:\env\maven\repo\org\springframework\spring-context\5.2.7.RELEASE\spring-context-5.2.7.RELEASE.jar;D:\env\maven\repo\org\springframework\spring-expression\5.2.7.RELEASE\spring-expression-5.2.7.RELEASE.jar;D:\env\maven\repo\org\springframework\boot\spring-boot-starter-test\2.3.1.RELEASE\spring-boot-starter-test-2.3.1.RELEASE.jar;D:\env\maven\repo\org\springframework\boot\spring-boot-test\2.3.1.RELEASE\spring-boot-test-2.3.1.RELEASE.jar;D:\env\maven\repo\org\springframework\boot\spring-boot-test-autoconfigure\2.3.1.RELEASE\spring-boot-test-autoconfigure-2.3.1.RELEASE.jar;D:\env\maven\repo\com\jayway\jsonpath\json-path\2.4.0\json-path-2.4.0.jar;D:\env\maven\repo\net\minidev\json-smart\2.3\json-smart-2.3.jar;D:\env\maven\repo\net\minidev\accessors-smart\1.2\accessors-smart-1.2.jar;D:\env\maven\repo\org\ow2\asm\asm\5.0.4\asm-5.0.4.jar;D:\env\maven\repo\jakarta\xml\bind\jakarta.xml.bind-api\2.3.3\jakarta.xml.bind-api-2.3.3.jar;D:\env\maven\repo\jakarta\activation\jakarta.activation-api\1.2.2\jakarta.activation-api-1.2.2.jar;D:\env\maven\repo\org\assertj\assertj-core\3.16.1\assertj-core-3.16.1.jar;D:\env\maven\repo\org\hamcrest\hamcrest\2.2\hamcrest-2.2.jar;D:\env\maven\repo\org\junit\jupiter\junit-jupiter\5.6.2\junit-jupiter-5.6.2.jar;D:\env\maven\repo\org\junit\jupiter\junit-jupiter-api\5.6.2\junit-jupiter-api-5.6.2.jar;D:\env\maven\repo\org\opentest4j\opentest4j\1.2.0\opentest4j-1.2.0.jar;D:\env\maven\repo\org\junit\platform\junit-platform-commons\1.6.2\junit-platform-commons-1.6.2.jar;D:\env\maven\repo\org\junit\jupiter\junit-jupiter-params\5.6.2\junit-jupiter-params-5.6.2.jar;D:\env\maven\repo\org\junit\jupiter\junit-jupiter-engine\5.6.2\junit-jupiter-engine-5.6.2.jar;D:\env\maven\repo\org\junit\vintage\junit-vintage-engine\5.6.2\junit-vintage-engine-5.6.2.jar;D:\env\maven\repo\org\apiguardian\apiguardian-api\1.1.0\apiguardian-api-1.1.0.jar;D:\env\maven\repo\org\junit\platform\junit-platform-engine\1.6.2\junit-platform-engine-1.6.2.jar;D:\env\maven\repo\junit\junit\4.13\junit-4.13.jar;D:\env\maven\repo\org\mockito\mockito-core\3.3.3\mockito-core-3.3.3.jar;D:\env\maven\repo\net\bytebuddy\byte-buddy\1.10.11\byte-buddy-1.10.11.jar;D:\env\maven\repo\net\bytebuddy\byte-buddy-agent\1.10.11\byte-buddy-agent-1.10.11.jar;D:\env\maven\repo\org\objenesis\objenesis\2.6\objenesis-2.6.jar;D:\env\maven\repo\org\mockito\mockito-junit-jupiter\3.3.3\mockito-junit-jupiter-3.3.3.jar;D:\env\maven\repo\org\skyscreamer\jsonassert\1.5.0\jsonassert-1.5.0.jar;D:\env\maven\repo\com\vaadin\external\google\android-json\0.0.20131108.vaadin1\android-json-0.0.20131108.vaadin1.jar;D:\env\maven\repo\org\springframework\spring-core\5.2.7.RELEASE\spring-core-5.2.7.RELEASE.jar;D:\env\maven\repo\org\springframework\spring-jcl\5.2.7.RELEASE\spring-jcl-5.2.7.RELEASE.jar;D:\env\maven\repo\org\springframework\spring-test\5.2.7.RELEASE\spring-test-5.2.7.RELEASE.jar;D:\env\maven\repo\org\xmlunit\xmlunit-core\2.7.0\xmlunit-core-2.7.0.jar;D:\env\maven\repo\io\springfox\springfox-swagger2\2.9.2\springfox-swagger2-2.9.2.jar;D:\env\maven\repo\io\swagger\swagger-annotations\1.5.20\swagger-annotations-1.5.20.jar;D:\env\maven\repo\io\swagger\swagger-models\1.5.20\swagger-models-1.5.20.jar;D:\env\maven\repo\com\fasterxml\jackson\core\jackson-annotations\2.11.0\jackson-annotations-2.11.0.jar;D:\env\maven\repo\io\springfox\springfox-spi\2.9.2\springfox-spi-2.9.2.jar;D:\env\maven\repo\io\springfox\springfox-core\2.9.2\springfox-core-2.9.2.jar;D:\env\maven\repo\io\springfox\springfox-schema\2.9.2\springfox-schema-2.9.2.jar;D:\env\maven\repo\io\springfox\springfox-swagger-common\2.9.2\springfox-swagger-common-2.9.2.jar;D:\env\maven\repo\io\springfox\springfox-spring-web\2.9.2\springfox-spring-web-2.9.2.jar;D:\env\maven\repo\com\google\guava\guava\20.0\guava-20.0.jar;D:\env\maven\repo\com\fasterxml\classmate\1.5.1\classmate-1.5.1.jar;D:\env\maven\repo\org\slf4j\slf4j-api\1.7.30\slf4j-api-1.7.30.jar;D:\env\maven\repo\org\springframework\plugin\spring-plugin-core\1.2.0.RELEASE\spring-plugin-core-1.2.0.RELEASE.jar;D:\env\maven\repo\org\springframework\plugin\spring-plugin-metadata\1.2.0.RELEASE\spring-plugin-metadata-1.2.0.RELEASE.jar;D:\env\maven\repo\org\mapstruct\mapstruct\1.2.0.Final\mapstruct-1.2.0.Final.jar;D:\env\maven\repo\io\springfox\springfox-swagger-ui\2.9.2\springfox-swagger-ui-2.9.2.jar;D:\env\maven\repo\org\openjdk\jol\jol-core\0.10\jol-core-0.10.jar;D:\env\maven\repo\org\projectlombok\lombok\1.16.10\lombok-1.16.10.jar" com.oyb.jvm.test03.lesson06.GcTest01
--------创建2M后--------
--------创建2M后--------
{Heap before GC invocations=1 (full 0):
PSYoungGen total 9216K, used 7242K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
eden space 8192K, 88% used [0x00000000ff600000,0x00000000ffd12b18,0x00000000ffe00000)
from space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
to space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
ParOldGen total 20480K, used 0K [0x00000000fe200000, 0x00000000ff600000, 0x00000000ff600000)
object space 20480K, 0% used [0x00000000fe200000,0x00000000fe200000,0x00000000ff600000)
Metaspace used 3249K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 349K, capacity 388K, committed 512K, reserved 1048576K
[GC (Allocation Failure) [PSYoungGen: 7242K->1016K(9216K)] 7242K->5237K(29696K), 0.0048569 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
Heap after GC invocations=1 (full 0):
PSYoungGen total 9216K, used 1016K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
eden space 8192K, 0% used [0x00000000ff600000,0x00000000ff600000,0x00000000ffe00000)
from space 1024K, 99% used [0x00000000ffe00000,0x00000000ffefe010,0x00000000fff00000)
to space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
ParOldGen total 20480K, used 4221K [0x00000000fe200000, 0x00000000ff600000, 0x00000000ff600000)
object space 20480K, 20% used [0x00000000fe200000,0x00000000fe61f708,0x00000000ff600000)
Metaspace used 3249K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 349K, capacity 388K, committed 512K, reserved 1048576K
}
--------创建2M后--------
Heap
PSYoungGen total 9216K, used 3230K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
eden space 8192K, 27% used [0x00000000ff600000,0x00000000ff8298e8,0x00000000ffe00000)
from space 1024K, 99% used [0x00000000ffe00000,0x00000000ffefe010,0x00000000fff00000)
to space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
ParOldGen total 20480K, used 4221K [0x00000000fe200000, 0x00000000ff600000, 0x00000000ff600000)
object space 20480K, 20% used [0x00000000fe200000,0x00000000fe61f708,0x00000000ff600000)
Metaspace used 3270K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 351K, capacity 388K, committed 512K, reserved 1048576K
Process finished with exit code 0
GC (Allocation Failure) [PSYoungGen: 7242K->1016K(9216K)] 7242K->5237K(29696K), 0.0048569 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
GC (Allocation Failure) :对象分配失效,此时就要出发一次Young GC
(9216K):年轻代可用空间是9216KB,也就是9MB。Eden区是8MB,两个Survivor中只有一个是可以放存活对象的,另外一个是必须一直保持空闲的,所以他考虑年轻代的可用可见,就是Eden+1个Survivor-from的大小,也就是9MB。
7316K->1016K:意思就是对年轻代执行了一次GC,GC之前都使用了7316KB了,但是GC之后只有1016K的对象是存活下来。
7242K->5237K(29696K)
7242K GC前堆内存占用
5237K GC后堆内存占用
29696K 堆内存总量
0.0048569 secs 这个就是本次gc耗费的时间,大概耗费了4.8ms,仅仅是回收2MB的对象而已
(Allocation Failure)
上面有Heap before 代表Young GC之前的堆情况
下面有Heap after 代表Young GC之后的堆情况
Heap after GC invocations=1 (full 0):
PSYoungGen total 9216K, used 1016K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
eden space 8192K, 0% used [0x00000000ff600000,0x00000000ff600000,0x00000000ffe00000)
from space 1024K, 99% used [0x00000000ffe00000,0x00000000ffefe010,0x00000000fff00000)
to space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
ParOldGen total 20480K, used 4221K [0x00000000fe200000, 0x00000000ff600000, 0x00000000ff600000)
object space 20480K, 20% used [0x00000000fe200000,0x00000000fe61f708,0x00000000ff600000)
Metaspace used 3249K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 349K, capacity 388K, committed 512K, reserved 1048576K
PSYoungGen中最前面的PS代表垃圾收集器时Parallel垃圾收集器,回收的区域是新生代(YoungGen);
ParOldGen中最前面的Par代表垃圾收集器时Parallel Old收集器,回收的区域是老年代(OldGen);
Metaspace元数据空间和Class空间,存放一些类信息、常量池之类的东西。
疑问:
在分配了4M之后,再分配2m,就出现了young gc,Eden区 8m,居然装不下6m,为什么呢?
PSYoungGen total 9216K, used 7242K
分配了4m后,就达到了7242K,如果再分配7242K+ 2048K = 9290K
为什么本来9m,分配4m就达到了7242k,然后分配2m,就超过了9m?