模拟代码以及JVM设置:
public
class
OOMTest {
//JVM设置
//-Xms30M -Xmx30M -Xmn10M -XX:+PrintGCDetails -XX:PermSize=10m -XX:MaxPermSize=10m -XX:+UseConcMarkSweepGC -XX:+HeapDumpOnOutOfMemoryError
static
class
OOMObject {
}
public
static
void
main(String[] args) {
List
new
ArrayList
while
(
true
) {
list.add(
new
OOMObject());
}
}
}
|
预备知识——CMS清理过程:
CMS的gc日志分为一下几个步骤,重点关注initial-mark和remark这两个阶段,因为这两个阶段会stop进程。
初始标记(init mark):收集根引用,这是一个stop-the-world阶段。
并发标记(concurrent mark):这个阶段可以和用户应用并发进行。遍历老年代的对象图,标记出活着的对象。
并发预清理(concurrent preclean):这同样是一个并发的阶段。主要的用途也是用来标记,用来标记那些在前面标记之后,
发生变化的引用。主要是为了缩短remark阶段的stop-the-world的时间。
重新标记(remark):这是一个stop-the-world的操作。暂停各个应用,统计那些在发生变化的标记。
并发清理(concurrent sweep):并发扫描整个老年代,回收一些在对象图中不可达对象所占用的空间。
并发重置(concurrent reset):重置某些数据结果,以备下一个回收周期
运行日志解读:
[GC [ParNew: 7936K->1024K(9216K),
0.0351710
secs] 7936K->5613K(29696K),
0.0352000
secs] [Times: user=
0.14
sys=
0.02
, real=
0.03
secs]
[GC [ParNew: 9216K->1024K(9216K),
0.0136330
secs] 13805K->12213K(29696K),
0.0136510
secs] [Times: user=
0.07
sys=
0.00
, real=
0.02
secs]
[GC [
1
CMS-initial-mark: 11189K(20480K)] 12330K(29696K),
0.0018950
secs] [Times: user=
0.00
sys=
0.00
, real=
0.00
secs]
[GC [ParNew (promotion failed): 9216K->9216K(9216K),
2.2553270
secs][CMS[CMS-concurrent-mark:
0.035
/
2.290
secs] [Times: user=
2.84
sys=
0.75
, real=
2.29
secs]
(concurrent mode failure): 19558K->20479K(20480K),
0.1047330
secs] 20405K->21027K(29696K), [CMS Perm : 3055K->3053K(10240K)],
2.3601020
secs] [Times: user=
2.90
sys=
0.75
, real=
2.36
secs]
[Full GC [CMS: 20479K->19878K(20480K),
0.0880600
secs] 29695K->26772K(29696K), [CMS Perm : 3056K->3056K(10240K)],
0.0880850
secs] [Times: user=
0.09
sys=
0.00
, real=
0.09
secs]
[GC [
1
CMS-initial-mark: 19878K(20480K)] 26863K(29696K),
0.0080270
secs] [Times: user=
0.01
sys=
0.00
, real=
0.01
secs]
[Full GC [CMS[CMS-concurrent-mark:
0.026
/
0.037
secs] [Times: user=
0.07
sys=
0.01
, real=
0.04
secs]
(concurrent mode failure): 20479K->20476K(20480K),
0.1131200
secs] 29695K->29608K(29696K), [CMS Perm : 3056K->3056K(10240K)],
0.1131460
secs] [Times: user=
0.13
sys=
0.00
, real=
0.11
secs]
[Full GC [CMS: 20479K->20447K(20480K),
0.0847510
secs] 29695K->29663K(29696K), [CMS Perm : 3056K->3056K(10240K)],
0.0847740
secs] [Times: user=
0.09
sys=
0.00
, real=
0.09
secs]
[GC [
1
CMS-initial-mark: 20447K(20480K)] 29663K(29696K),
0.0099760
secs] [Times: user=
0.01
sys=
0.00
, real=
0.01
secs]
[Full GC [CMS[CMS-concurrent-mark:
0.026
/
0.028
secs] [Times: user=
0.05
sys=
0.00
, real=
0.03
secs]
(concurrent mode failure): 20479K->20479K(20480K),
0.0951170
secs] 29695K->29695K(29696K), [CMS Perm : 3056K->3056K(10240K)],
0.0951400
secs] [Times: user=
0.12
sys=
0.00
, real=
0.10
secs]
[Full GC [CMS: 20479K->20479K(20480K),
0.0661090
secs] 29695K->29695K(29696K), [CMS Perm : 3056K->3056K(10240K)],
0.0661430
secs] [Times: user=
0.06
sys=
0.00
, real=
0.06
secs]
java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid88950.hprof ...
Heap dump file created [
39331031
bytes in
0.273
secs]
[GC [
1
CMS-initial-mark: 20479K(20480K)] 29695K(29696K),
0.0120230
secs] [Times: user=
0.01
sys=
0.00
, real=
0.02
secs]
[Full GC [CMS[CMS-concurrent-mark:
0.028
/
0.029
secs] [Times: user=
0.05
sys=
0.00
, real=
0.03
secs]
(concurrent mode failure)Exception in thread
"main"
: 20480K->778K(20480K),
0.0494630
secs] 29695K->778K(29696K), [CMS Perm : 3056K->3056K(10240K)],
0.0494890
secs] [Times: user=
0.07
sys=
0.00
, real=
0.05
secs]
java.lang.OutOfMemoryError: Java heap space
at jvm.OOMTest.main(OOMTest.java:
25
)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
57
)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
43
)
at java.lang.reflect.Method.invoke(Method.java:
601
)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:
140
)
Heap
par
new
generation total 9216K, used 150K [
0x00000007fd800000
,
0x00000007fe200000
,
0x00000007fe200000
)
eden space 8192K,
1
% used [
0x00000007fd800000
,
0x00000007fd8258f8
,
0x00000007fe000000
)
from space 1024K,
0
% used [
0x00000007fe100000
,
0x00000007fe100000
,
0x00000007fe200000
)
to space 1024K,
0
% used [
0x00000007fe000000
,
0x00000007fe000000
,
0x00000007fe100000
)
concurrent mark-sweep generation total 20480K, used 778K [
0x00000007fe200000
,
0x00000007ff600000
,
0x00000007ff600000
)
concurrent-mark-sweep perm gen total 10240K, used 3089K [
0x00000007ff600000
,
0x0000000800000000
,
0x0000000800000000
)
日志解读:
1
、[GC (Young GC)[ParNew(使用ParNew作为年轻代的垃圾回收期): 7936K(年轻代垃圾回收前的大小)->1024K(年轻代垃圾回收后的大小)(9216K 年轻代容量),
0.0351710
secs(回收时间)] 7936K(整个heap垃圾回收前的大小)->5613K(整个heap垃圾回收后的大小)(
29696
(整个heap容量大小)),
0.0352000
secs(回收时间)] [Times: user=
0.14
(Young GC用户耗时)
sys=
0.02
(系统耗时), real=
0.03
secs(真实耗时)]
2
、[GC [
1
CMS-initial-mark(初始标记,收集跟引用): 11189K(老年代使用内存)(20480K老年代容量)] 12330K(对内存使用内存)(29696K对内存容量),
0.0018950
secs] [Times: user=
0.00
sys=
0.00
, real=
0.00
secs]
3
、[GC [ParNew (promotion failed一般发生在新生代晋升老年代时,老年代空间不够或连续空间不够却还没达到old区的触发值,引发Full Gc.): 9216K->9216K(9216K),
2.2553270
secs]
4
、[CMS[CMS-concurrent-mark并发标记:
0.035
实际标记时间/
2.290
总并发标记时间 secs] [Times: user=
2.84
sys=
0.75
, real=
2.29
secs]
5
、(concurrent mode failure一般发生在CMS GC 运行过程中,老年代空间不足,引发Full GC): 19558K->20479K(20480K),
0.1047330
secs] 20405K->21027K(29696K), [CMS Perm : 3055K->3053K(10240K)],
2.3601020
secs] [Times: user=
2.90
sys=
0.75
, real=
2.36
secs]
6
、[Full GC一次Full GC的整体效果[CMS: 20479K->19878K(20480K),
0.0880600
secs] 29695K->26772K(29696K), [CMS Perm : 3056K->3056K(10240K)],
0.0880850
secs] [Times: user=
0.09
sys=
0.00
, real=
0.09
secs]
7
、java.lang.OutOfMemoryError: Java heap space报错信息,堆内存溢出。
8
、Dumping heap to java_pid88950.hprof ...堆内存映像保存文件和大小。
Heap dump file created [
39331031
bytes in
0.273
secs]
|
内存快照java_pid88950.hprof分析:
模拟代码及JVM参数设置:
public
class
JavaStackOverFlowTest {
//-Xms30M -Xmx30M -Xmn10M -XX:+PrintGCDetails -XX:PermSize=2m -XX:MaxPermSize=2m -XX:+UseConcMarkSweepGC -XX:+HeapDumpOnOutOfMemoryError
private
int
stackLength =
1
;
public
void
stackLeak() {
stackLength++;
stackLeak();
}
public
static
void
main(String[] args)
throws
Throwable {
JavaStackOverFlowTest oom =
new
JavaStackOverFlowTest();
try
{
oom.stackLeak();
}
catch
(Throwable e) {
System.out.println(
"stack length:"
+ oom.stackLength);
throw
e;
}
}
}
|
运行日志:
Exception in thread
"main"
java.lang.StackOverflowError
stack length:
10806
at jvm.JavaStackOverFlowTest.stackLeak(JavaStackOverFlowTest.java:
20
)
at jvm.JavaStackOverFlowTest.stackLeak(JavaStackOverFlowTest.java:
21
)
at jvm.JavaStackOverFlowTest.stackLeak(JavaStackOverFlowTest.java:
21
)
at jvm.JavaStackOverFlowTest.stackLeak(JavaStackOverFlowTest.java:
21
)
at jvm.JavaStackOverFlowTest.stackLeak(JavaStackOverFlowTest.java:
21
)
at jvm.JavaStackOverFlowTest.stackLeak(JavaStackOverFlowTest.java:
21
)
|
模拟代码及JVM参数设置:
public
class
RunConstantOOMTest {
//-Xms30M -Xmx30M -Xmn10M -XX:+PrintGCDetails -XX:PermSize=2m -XX:MaxPermSize=2m -XX:+UseConcMarkSweepGC -XX:+HeapDumpOnOutOfMemoryError
public
static
void
main(String[] args) {
// 使用List保持着常量池引用,避免Full GC回收常量池行为
List
new
ArrayList
int
i =
0
;
while
(
true
) {
list.add(String.valueOf(i++).intern());
}
}
}
|
运行日志以及解读:
[Full GC [CMS: 0K->221K(20480K),
0.0048730
secs] 367K->221K(29696K), [CMS Perm : 2047K->2046K(2048K)],
0.0049090
secs] [Times: user=
0.00
sys=
0.00
, real=
0.01
secs]
[Full GC [CMS: 221K->210K(20480K),
0.0024700
secs] 221K->210K(29696K), [CMS Perm : 2046K->2046K(2048K)],
0.0024890
secs] [Times: user=
0.00
sys=
0.00
, real=
0.00
secs]
java.lang.OutOfMemoryError: PermGen space
Dumping heap to java_pid89325.hprof ...
[Full GC [CMS: 210K->210K(20480K),
0.0020000
secs] 210K->210K(29696K), [CMS Perm : 2046K->2046K(2048K)],
0.0020180
secs] [Times: user=
0.01
sys=
0.00
, real=
0.00
secs]
Heap dump file created [
553652
bytes in
0.010
secs]
[Full GC [CMS: 210K->210K(20480K),
0.0022670
secs] 210K->210K(29696K), [CMS Perm : 2046K->2026K(2048K)],
0.0022870
secs] [Times: user=
0.00
sys=
0.00
, real=
0.00
secs]
Error occurred during initialization of VM
java.lang.OutOfMemoryError: PermGen space
at java.util.concurrent.locks.ReentrantLock.
262
)
at java.util.concurrent.ConcurrentHashMap$Segment.
425
)
at java.util.concurrent.ConcurrentHashMap.
825
)
at sun.util.locale.LocaleObjectCache.
48
)
at sun.util.locale.LocaleObjectCache.
44
)
at java.util.Locale$Cache.
676
)
at java.util.Locale$Cache.
675
)
at java.util.Locale.
411
)
1
、java.lang.OutOfMemoryError: PermGen space
内存溢出,并且指出是Pern控件溢出。
|
内存快照java_pid89325.hprof分析:
从中可以看出,Perm区引发的Full Gc效果很不明显,并且打印出来的内存映射快照,不包括Perm区的内存。
模拟代码及JVM参数设置:
public
class
MethodAreaOOMTest {
//-Xms30M -Xmx30M -Xmn10M -XX:+PrintGCDetails -XX:PermSize=10m -XX:MaxPermSize=10m -XX:+UseConcMarkSweepGC -XX:+HeapDumpOnOutOfMemoryError
public
static
void
main(String[] args) {
while
(
true
) {
Enhancer enhancer =
new
Enhancer();
enhancer.setSuperclass(OOMObject.
class
);
enhancer.setUseCache(
false
);
enhancer.setCallback(
new
MethodInterceptor() {
public
Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)
throws
Throwable {
return
proxy.invokeSuper(obj, args);
}
});
enhancer.create();
}
}
static
class
OOMObject {
}
}
|
运行是日志分析:
GC [ParNew: 8192K->1023K(9216K),
0.0023860
secs] 8192K->1833K(29696K),
0.0024110
secs] [Times: user=
0.01
sys=
0.01
, real=
0.00
secs]
[GC [ParNew: 9215K->746K(9216K),
0.0048310
secs] 10025K->2498K(29696K),
0.0048490
secs] [Times: user=
0.02
sys=
0.00
, real=
0.01
secs]
[GC [ParNew: 8938K->577K(9216K),
0.0010750
secs] 10690K->2329K(29696K),
0.0010930
secs] [Times: user=
0.01
sys=
0.00
, real=
0.00
secs]
[GC [ParNew: 8769K->663K(9216K),
0.0015340
secs] 10521K->2415K(29696K),
0.0015720
secs] [Times: user=
0.01
sys=
0.00
, real=
0.01
secs]
[GC [ParNew: 8855K->661K(9216K),
0.0032120
secs] 10607K->2647K(29696K),
0.0032350
secs] [Times: user=
0.02
sys=
0.00
, real=
0.00
secs]
[GC [ParNew: 8853K->953K(9216K),
0.0020750
secs] 10839K->2938K(29696K),
0.0020930
secs] [Times: user=
0.01
sys=
0.00
, real=
0.01
secs]
[GC [ParNew: 9145K->701K(9216K),
0.0014820
secs] 11130K->2851K(29696K),
0.0015030
secs] [Times: user=
0.00
sys=
0.00
, real=
0.01
secs]
[GC [ParNew: 8893K->712K(9216K),
0.0011870
secs] 11043K->2862K(29696K),
0.0012040
secs] [Times: user=
0.01
sys=
0.00
, real=
0.00
secs]
[GC [ParNew: 8904K->947K(9216K),
0.0015220
secs] 11054K->3223K(29696K),
0.0015400
secs] [Times: user=
0.01
sys=
0.00
, real=
0.00
secs]
[GC [ParNew: 9139K->666K(9216K),
0.0011920
secs] 11415K->3056K(29696K),
0.0012070
secs] [Times: user=
0.00
sys=
0.00
, real=
0.00
secs]
[GC [ParNew: 8858K->558K(9216K),
0.0011120
secs] 11248K->3060K(29696K),
0.0011310
secs] [Times: user=
0.01
sys=
0.00
, real=
0.00
secs]
[GC [ParNew: 8750K->708K(9216K),
0.0014650
secs] 11252K->3309K(29696K),
0.0014900
secs] [Times: user=
0.01
sys=
0.00
, real=
0.00
secs]
[GC [ParNew: 8900K->834K(9216K),
0.0010410
secs] 11501K->3543K(29696K),
0.0010570
secs] [Times: user=
0.01
sys=
0.00
, real=
0.00
secs]
[GC [ParNew: 9026K->789K(9216K),
0.0011080
secs] 11735K->3497K(29696K),
0.0011270
secs] [Times: user=
0.00
sys=
0.00
, real=
0.00
secs]
[GC [ParNew: 8981K->870K(9216K),
0.0018110
secs] 11689K->3766K(29696K),
0.0018310
secs] [Times: user=
0.00
sys=
0.00
, real=
0.00
secs]
[GC [ParNew: 9062K->747K(9216K),
0.0015880
secs] 11958K->3842K(29696K),
0.0016030
secs] [Times: user=
0.01
sys=
0.00
, real=
0.00
secs]
[GC [ParNew: 8939K->704K(9216K),
0.0009460
secs] 12034K->3798K(29696K),
0.0009630
secs] [Times: user=
0.00
sys=
0.00
, real=
0.00
secs]
[GC [ParNew: 8896K->896K(9216K),
0.0011260
secs] 11990K->4102K(29696K),
0.0011440
secs] [Times: user=
0.01
sys=
0.00
, real=
0.00
secs]
[GC [ParNew: 9088K->823K(9216K),
0.0009460
secs] 12294K->4135K(29696K),
0.0009660
secs] [Times: user=
0.00
sys=
0.00
, real=
0.00
secs]
[Full GC [CMS: 3312K->3044K(20480K),
0.0271780
secs] 4471K->3044K(29696K), [CMS Perm : 10239K->10236K(10240K)],
0.0272090
secs] [Times: user=
0.07
sys=
0.00
, real=
0.03
secs]
[Full GC [CMS: 3044K->3072K(20480K),
0.0181400
secs] 3290K->3072K(29696K), [CMS Perm : 10239K->10239K(10240K)],
0.0181620
secs] [Times: user=
0.02
sys=
0.00
, real=
0.02
secs]
[Full GC [CMS: 3072K->1834K(20480K),
0.0155940
secs] 3072K->1834K(29696K), [CMS Perm : 10239K->10236K(10240K)],
0.0156160
secs] [Times: user=
0.02
sys=
0.00
, real=
0.02
secs]
[Full GC [CMS: 1834K->1842K(20480K),
0.0149900
secs] 2080K->1842K(29696K), [CMS Perm : 10239K->10239K(10240K)],
0.0150120
secs] [Times: user=
0.01
sys=
0.00
, real=
0.01
secs]
[Full GC [CMS: 1842K->1840K(20480K),
0.0132320
secs] 1925K->1840K(29696K), [CMS Perm : 10239K->10239K(10240K)],
0.0132540
secs] [Times: user=
0.02
sys=
0.00
, real=
0.01
secs]
java.lang.OutOfMemoryError: PermGen space
Dumping heap to java_pid89368.hprof ...
Heap dump file created [
3395371
bytes in
0.033
secs]
[Full GC [CMS: 1840K->1794K(20480K),
0.0127750
secs] 2005K->1794K(29696K), [CMS Perm : 10239K->10237K(10240K)],
0.0128040
secs] [Times: user=
0.01
sys=
0.00
, real=
0.01
secs]
[Full GC [CMS: 1794K->1794K(20480K),
0.0139640
secs] 1794K->1794K(29696K), [CMS Perm : 10237K->10237K(10240K)],
0.0139850
secs] [Times: user=
0.01
sys=
0.00
, real=
0.02
secs]
[Full GC [CMSException in thread
"main"
: 1794K->1782K(20480K),
0.0160820
secs] 1958K->1782K(29696K), [CMS Perm : 10239K->10239K(10240K)],
0.0161040
secs] [Times: user=
0.02
sys=
0.00
, real=
0.01
secs]
[Full GC [CMS: 1782K->1782K(20480K),
0.0138930
secs] 1782K->1782K(29696K), [CMS Perm : 10239K->10239K(10240K)],
0.0139150
secs] [Times: user=
0.01
sys=
0.00
, real=
0.02
secs]
[Full GC [CMS
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread
"main"
: 1782K->1773K(20480K),
0.0158560
secs] 1946K->1773K(29696K), [CMS Perm : 10239K->10238K(10240K)],
0.0158780
secs] [Times: user=
0.02
sys=
0.00
, real=
0.01
secs]
[Full GC [CMS: 1773K->1771K(20480K),
0.0120200
secs] 1856K->1771K(29696K), [CMS Perm : 10238K->10238K(10240K)],
0.0120410
secs] [Times: user=
0.01
sys=
0.00
, real=
0.01
secs]
Heap
par
new
generation total 9216K, used 82K [
0x0000000112ad0000
,
0x00000001134d0000
,
0x00000001134d0000
)
eden space 8192K,
1
% used [
0x0000000112ad0000
,
0x0000000112ae4a20
,
0x00000001132d0000
)
from space 1024K,
0
% used [
0x00000001133d0000
,
0x00000001133d0000
,
0x00000001134d0000
)
to space 1024K,
0
% used [
0x00000001132d0000
,
0x00000001132d0000
,
0x00000001133d0000
)
concurrent mark-sweep generation total 20480K, used 1771K [
0x00000001134d0000
,
0x00000001148d0000
,
0x00000001148d0000
)
concurrent-mark-sweep perm gen total 10240K, used 10238K [
0x00000001148d0000
,
0x00000001152d0000
,
0x00000001152d0000
)
|
和运行时常量池溢出一样,伴随着很多次效果不明显的Full GC,并且Perm区的内存快照不会进行保存。
案例分类
|
案例分析
|
案例现象
|
排查方法
|
解决方法
|
---|---|---|---|---|
JVM堆内存溢出。 |
1、CMS内存溢出案例。 现象:CMS一段时间不重启或者不发布,一般为两三天,晚上就会报警,报警内 容为Full GC,内存溢出。重启后问题马上就可以恢复。 分析:通过分析内存,发现下面这个类的interfaceMap占用了大部分内存,进而 发现是这个消息消费者线程Deal2Listener占用大部分内存。
结论:监听线程不同于用户请求线程,不会在用户请求结束后主动释放内存,而 会一直存在这个线程,除非重启或者重新部署。而这个监听线程不断往线程缓存 中存入数据,并且垃圾回收期无法进行回收,最终导致堆内存溢出。 2、合作取数据库数据量过大导致堆内存溢出。
|
Full GC次数较多,并伴随着 java.lang.OutOfMemoryError: Java heap space下面的 报错信息 |
添加参数-XX: +HeapDumpOnOutOfMemoryError 找到对应的内存溢出内存快照, 用mat打开对应的内存快照, 来进行快照分析。 |
保存现场后 重启服务器。 分析内存快照 找到内存 溢出的原因, 修复代码。 |
Perm区内存溢出。 |
1、调用的jar包中有String.intern()的调用。 2、groovy脚本导致的FullGC问题。
|
jmap -heap 12004查看内存分配情况。 堆中还有大量的内存未使用,但是不断 进行Full GC,并且每次GC效果不明显。 |
查看permSize大小,看大小是否设置的合适,检查是否有大量的常量设置,检查是否有cglib等反射生成的代码。 |
代码中或者jar包有显示的String.intern()的调用,修复代码。 |
直接分配内存溢出 | 1、产品中心对内存设置过大,导致频繁Full GC。 JVM堆空间分配的内存过大,导致对外内存不够用,系统 不定期抛出内存溢出异常。
|
所有的堆内存和Perm区都压力不大,只有抛出异常时才进行Full GC。 (如果设置了-XX:+DisableExplicitGC开关的话,对中还有很多空闲内存,却不断抛出内存溢出异常) 添加参数-XX: +HeapDumpOnOutOfMemoryError 无任何内存映像文件产生。 |
在异常栈中能够找到Unsafe.allocateMemory等字样。
|
检查系统内存和JVM内存,看JVM内存设置的是否合理。 检查-Xss看线程堆栈是否设置的合理。 检查代码中是否有Socket的使用和JNI代码。 |
JVM线程打满。 |
4、外部调用超时、数据库连接超时、数据库死锁导致JVM线程打满。
|
系统接口调用出现502、504错误, 并伴随着一定的连接超时报错。 |
jstat -l 进程号,打印进程中的线程 栈信息,通过查看线程栈信息,找出进程中是否有Block或者Running的线程。 |
外部接口调用、数据库连接或者处理都有超时控制。 |
GC导致长时间停顿 |
5、JVM内存扩容后,不定期出现长时间失去响应的现象。 | 不定期出现长时间失去响应的现象 |
查看Full GC记录,发现Full GC的停顿时间过长 |
1、调整CMS收集器不设置为吞吐量 优先,或者设置最长停顿时间。 2、若干个虚拟机建立集群来充分利用硬件资源。 |
1、类加载和编译时间优化:JDK版本的选择、禁止字节码校验。
2、GC时间优化:JVM初始内存设置、GC收集器选择。
加上-Xint 禁止掉及时编译,总的启动时间从12s上升到了42s。
加上-Dfile.encoding=UTF-8 -Xmx1g -Xmn512m -XX:PermSize=128m -XX:MaxPermSize=128m 进行了3次Full GC。
加上 -Xms1g 后 ,没有进行Full GC。
加上-XX:+UseConcMarkSweepGC,选用虽然进行了16次Full GC,但是停顿时间比较短,看出CMS垃圾收集器的优越性。
参数调优基本都是基于实践,推荐的设置:JVM系列三:JVM参数设置、分析
-Xmx3000M -Xms3000M -Xmn600M -XX:PermSize=500M -XX:MaxPermSize=500M -Xss256K -XX:+DisableExplicitGC -XX:SurvivorRatio=4 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0 -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70
-XX:+HeapDumpOnOutOfMemoryError
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps
1、Q:CMS是否和Full GC等价?
A:1. Full GC == Major GC指的是对老年代/永久代的stop the world的GC
2. Full GC的次数 = 老年代GC时 stop the world的次数
3. Full GC的时间 = 老年代GC时 stop the world的总时间
4. CMS 不等于Full GC,我们可以看到CMS分为多个阶段,只有stop the world的阶段被计算到了Full GC的次数和时间
,而和业务线程并发的GC的次数和时间则不被认为是Full GC
5. Full GC本身不会先进行Minor GC,我们可以配置,让Full GC之前先进行一次Minor GC,因为老年代很多对象都会引用到新生代的对象,
先进行一次Minor GC可以提高老年代GC的速度。比如老年代使用CMS时,设置CMSScavengeBeforeRemark优化,让CMS remark之前先进行一次Minor GC。
2、Q:concurrent mode fail失败后,serial old会作为备选搜集器?
A:如果并发搜集器不能在年老代填满之前完成不可达(unreachable)对象的回收,或者年老代中有效的空闲内存空间不能满足某一个内存的分配请求,
此时应用会被暂停,并在此暂停期间开始垃圾回收,直到回收完成才会恢复应用程序。这种无法并发完成搜集的情况就成为并发模式失败(concurrent mode failure)。
在并发模式失败的情况下,serial old会作为备选搜集器,进行一次全局GC(Full GC),因此serial old也算是CMS的“替补”。
显然,由于serial old的介入,会造成较大的停顿时间。
参考:
http://www.open-open.com/lib/view/open1432109559864.html
http://blog.csdn.net/historyasamirror/article/details/6245157
http://ifeve.com/jvm-cms-log/
内存溢出异常实战
关于施用full gc频繁的分析及解决
JVM QA经典问答:http://blog.csdn.net/iter_zc/article/details/41802365
GC定义:http://www.tuicool.com/articles/jq2yIza
CMS GC MODE : http://blog.csdn.net/g7n3f/article/details/50828793