https://mp.weixin.qq.com/s/DloKDxkZfUuL_O-oABnk5Q
http://jagadesh4java.blogspot.com/2014/09/analyzing-jvm-crash.html
https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/crashes001.html
http://jagadesh4java.blogspot.com/2014/09/analyzing-jvm-crash.html
https://stackoverflow.com/questions/1000002/what-is-segv-maperr
1、JVM采用的是分代收集,不同的对象生命周期是不一样的,使用不同垃圾回收算法也不同,这是为了提高回收效率。
2、没有最好的收集器,也没有万能的收集器,只有最适合的收集器。
3、可以根据日志中分区的名称推断出使用的垃圾回收器。
4、垃圾回收期之间可以组合使用,在公司中比较常见的搭配为 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC,新生代使用ParNew,老年代使用CMS。当然使用CMS的前提是,可以提供更大的内存和更多的CPU(堆最少为3G内存以上,建议最小4G),也就是硬件比较好。
5、使用CMS垃圾回收时,通常还会配置如下几个参数:
-XX:+UseCMSInitiatingOccupancyOnly:
仅仅使用手动定义(CMSInitiatingOccupancyFraction)开始CMS收集。
-XX:CMSInitiatingOccupancyFraction=70:
CMS在年老代, 使用70%后开始CMS收集,如果你的年老代增长不是那么快,并且希望降低CMS次数的话,可以适当调高此值。
-XX:+CMSParallelRemarkEnabled:开启并行Remark,默认是开启的,所以可以不设置此参数。
6、经过我的测试,G1并没有比CMS表现更好,相反,CMS无论是吞吐率还是停顿时间,都比G1表现更好,不能相信网上的大话。当然这并不一定是CMS比G1更好,可能某些情况下,G1可能比CMS会好,只是我现在还不确定,如果有了解的同学欢迎留言。
HeapPSYoungGen total 1536K, used 531K [0x00000000ff980000, 0x00000000ffc80000, 0x0000000100000000)eden space 1024K, 3% used [0x00000000ff980000,0x00000000ff987c68,0x00000000ffa80000)from space 512K, 97% used [0x00000000ffa80000,0x00000000ffafd208,0x00000000ffb00000)to space 512K, 0% used [0x00000000ffc00000,0x00000000ffc00000,0x00000000ffc80000)ParOldGen total 13824K, used 13357K [0x00000000fec00000, 0x00000000ff980000, 0x00000000ff980000)object space 13824K, 96% used [0x00000000fec00000,0x00000000ff90b798,0x00000000ff980000)Metaspace used 2767K, capacity 4486K, committed 4864K, reserved 1056768Kclass space used 298K, capacity 386K, committed 512K, reserved 1048576K
详细解释如下,为了便于阅读,我把对应的解释标记成了不同的颜色:
PSYoungGen:垃圾回收类型,PS是Parallel Scavenge收集器的缩写,表示年轻代使用了Parallel Scavenge,它对应的新生代称为PSYoungGen,新生代又分为eden space、from space和to space这三部分。
需要注意的是,不同的新生代垃圾回收算法对应的名字也不相同,会有如下三种新生代垃圾回收算法,读者可以自行修改下面给出的参数,运行感受一下:
GC[ParNew,表示使用的是parNew收集器,对应的参数为 -XX:+UseSerialGC。
GC[DefNew,表示用的是serial收集器,对应的参数为 -XX:+UseParNewGC。
GC[PSYoungGen,表示用的是Parallel Scavenge收集器,对应的参数为 -XX:+UseParallelGC。
ParOldGen:Parallel Scavenge收集器配套的老年代。
它与新生代一样,不同的垃圾回收算法对应的名字也不相同:
tenured generation,表示使用的是Serial Old收集器。
ParOldGen,表示使用的是Parallel Old收集器。
concurrent mark-sweep generation,表示使用的是CMS收集器。
Metaspace:永久代。
total & used:总的空间和用掉的空间。
[GC (Allocation Failure) [PSYoungGen: 796K->504K(1536K)] 14108K->13896K(15360K), 0.0042751 secs] [Times: user=0.06 sys=0.00, real=0.00 secs][Full GC (Ergonomics) [PSYoungGen: 504K->502K(1536K)] [ParOldGen: 13392K->13368K(13824K)] 13896K->13870K(15360K), [Metaspace: 2735K->2735K(1056768K)], 0.0073296 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
详细解释如下,为了便于阅读,我把对应的解释标记成了不同的颜色:
GC & Full GC:表示垃圾回收时的停顿类型,GC针对年轻代;Full GC针对老年代,说明这次GC是发生了Stop-The-World,此时收集会暂停所有工作线程,会进行堆内存全扫描。这也是为什么不建议在程序中显式调用System.gc(),因为它会触发Full GC。
[PSYoungGen: 796K->504K(1536K)]:796K表示GC前的Young区占用;504K表示GC后的Young区占用;1536K表示Yong区总大小。
14108K->13896K(15360K):14108K表示YoungGC前的整个堆的占用;13896K表示YoungGC后的整个堆的占用;15360K表示整个堆的大小
0.0042751 secs:YoungGC的耗时。
[Times: user=0.06 sys=0.00, real=0.00 secs] :user用户态消耗CPU时间;sys内核消耗CPU时间;real标识从开始到结束所经过的墙钟时间(Wall Clock Time)。墙钟时间的意思是,从进程从开始运行到结束,时钟走过的时间,这其中包含了进程在阻塞和等待状态的时间,包含了各种非运算耗时,比如磁盘I/O耗时,线程阻塞等待时间等,而user和sys不包含这些,但当系统有多CPU或者多核的话,多线程操作会叠加这些CPU时间,所以user或sys时间超过real时间是完全正常的。
http://jagadesh4java.blogspot.com/2014/09/analyzing-jvm-crash.html
Current thread (0x0d0eb000): JavaThread "main" [_thread_in_native, id=9240, stack (0x044e0000, 0x046e0000)]
Current thread (0x0d0eb000): The Thread pointer is a pointer to the internal representation to the JVM internal thread structure.
JavaThread "main": The Java Thread that is currently running. This can change accordingly.
_thread_in_native: The Thread State.
Some other thread states include,
_thread_uninitialized: Thread is not created. This should never happen unless there's
memory corruption
_thread_new: Thread has been created but it has not yet started.
_thread_in_native: Thread is running native code. Probably a bug in native code.
_thread_in_vm: Thread is running VM code.
_thread_in_Java: Thread is running (either interpreted or compiled) Java code.
_thread_blocked: Thread is blocked.
..._trans: If you see any of the above states but followed by "_trans", it means
the thread is changing to a different state.
id=9240: The thread ID is the native Thread ID also seen as nid in Thread dumps.
In the above line, the “C” is called a Native C Frame. We do have some other frames as
C -Native C frame
J –Other frame types including compiled Java frames
j -Interpreted Java frames
V -VM frames
v –VM generated stub frame
http://jagadesh4java.blogspot.com/2014/09/analyzing-jvm-crash.html
The crash report tells the error has happened in JIT compiler thread:
Current thread (0x00007f89e481c800): JavaThread "C2 CompilerThread1"
https://plumbr.io/jvm-crashhttps://stackoverflow.com/questions/1000002/what-is-segv-maperr
There are two common kinds of SEGV, which is an error that results from an invalid memory access:
- A page was accessed which had the wrong permissions. E.g., it was read-only but your code tried to write to it. This will be reported as SEGV_ACCERR.
- A page was accessed that is not even mapped into the address space of the application at all. This will often result from dereferencing a null pointer or a pointer that was corrupted with a small integer value. This is reported as SEGV_MAPERR.cr