算是笔记吧。看了很多次的jvm、gc,但都没记住。这次遇到了自己写得线上服务出现了oom+死锁+频繁full gc(扶额),总算是记住了jvm和gc的基础知识。也是醉了。
jvm模型
主要分3个模块吧:堆、栈、本地方法栈。
堆=young(eden + survivor(from + to)) + tenured + permanent,也有说permanent不属于堆的,不过从gc日志来看我更倾向前者,但从gc参数来看应该是后者。
结合java8的gc来看:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
2016-10-21T15:21:21.574+0800: 3911.507: [GC (Allocation Failure) 2016-10-21T15:21:21.574+0800: 3911.508: [ParNew Desired survivor size 107347968 bytes, new threshold 6 (max 6) - age 1: 80985024 bytes, 80985024 total : 1677824K->79138K(1887488K), 0.1383027 secs] 1677824K->79138K(5033216K), 0.1384487 secs] [Times: user=0.16 sys=0.05, real=0.13 secs] Heap after GC invocations=1 (full 1): par new generation total 1887488K, used 79138K [0x0000000680000000, 0x0000000700000000, 0x0000000700000000) eden space 1677824K, 0% used [0x0000000680000000, 0x0000000680000000, 0x00000006e6680000) from space 209664K, 37% used [0x00000006f3340000, 0x00000006f8088818, 0x0000000700000000) to space 209664K, 0% used [0x00000006e6680000, 0x00000006e6680000, 0x00000006f3340000) concurrent mark-sweep generation total 3145728K, used 0K [0x0000000700000000, 0x00000007c0000000, 0x00000007c0000000) Metaspace used 50763K, capacity 51092K, committed 51552K, reserved 1093632K class space used 7982K, capacity 8081K, committed 8088K, reserved 1048576K } {Heap before GC invocations=1 (full 1): par new generation total 1887488K, used 1756962K [0x0000000680000000, 0x0000000700000000, 0x0000000700000000) eden space 1677824K, 100% used [0x0000000680000000, 0x00000006e6680000, 0x00000006e6680000) from space 209664K, 37% used [0x00000006f3340000, 0x00000006f8088818, 0x0000000700000000) to space 209664K, 0% used [0x00000006e6680000, 0x00000006e6680000, 0x00000006f3340000) concurrent mark-sweep generation total 3145728K, used 0K [0x0000000700000000, 0x00000007c0000000, 0x00000007c0000000) Metaspace used 51090K, capacity 51412K, committed 51808K, reserved 1093632K class space used 7984K, capacity 8081K, committed 8088K, reserved 1048576K |
young
par new generation就是新生代young,其大小等于eden区+from/to区,注意这里不是eden+from+to。为什么呢?因为你永远不能同时使用from和to。eden、from和to的比例默认是8:1:1,可以通过参数
新对象的分配发生eden区域内,当新对象(非大对象)无法在该区域分配时便引发Minor GC。大对象放不下的时候直接去tenured区分配。Minor GC就是将eden+from/to的存活对象copy到to/from中去,顺带存活了若干次的会放到tenured区,而且放不下的也会去old区。
(更多…)