最近几天线上服务器内存一直报警,物理内存持续超过 90%,导致监控一直报警。
线上服务器 tomcat 启动参数:
-Xms3072m -Xmx3072m -XX:PermSize=256m -XX:MaxPermSize=256m -Xmn1024m -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=80 -XX:+UseCMSCompactAtFullCollection -XX:+HeapDumpOnOutOfMemoryError
服务器配置:
双核 4GB 内存
通过本地和开发环境模拟测试:
当 tomcat 启动之后内存并没有占用到 3GB 的内存,只有 1GB 左右。然后通过一段测试代码将内存耗光(代码如下):
HashMap<Object,Object> map = new HashMap<>();
Integer i= 1;
flag1 = flag;
for(;;) {
i++;
if(flag1 == 1) {
map.put(i, i+1);
}else {
break;
}
}
然后系统一直会执行 Full GC,直到抛出 OutOfMemoryError 为止。但是如果在系统开始 Full GC 之后马上终止程序,
这个时候 JVM 的堆内存使用会释放至正常范围,但是通过系统命令查看 JVM 的内存占用发现内存一直没有释放。
因为对于操作系统,请求内存的系统调用会占用大量的 cpu 时间,所以频繁的请求、释放内存将会导致性能的严重下降。所以对于 jvm 最好的方式就是尽量多占用内存作为 heap,少释放甚至不释放空闲的 heap 给操作系统以减少消耗在内存请求、释放操作上的 cpu 时间。
所以导致 JVM 内存一直占用过高,但是通过打印堆栈的使用情况来看,堆内存的使用率并不是很高,再加上系统的占用以及其他应用对内存的占用,所以会导致监控平台内存告警。
using parallel threads in the new generation.
using thread-local object allocation.
Concurrent Mark-Sweep GC
Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 3221225472 (3072.0MB)
NewSize = 1073741824 (1024.0MB)
MaxNewSize = 1073741824 (1024.0MB)
OldSize = 5439488 (5.1875MB)
NewRatio = 2
SurvivorRatio = 8
PermSize = 268435456 (256.0MB)
MaxPermSize = 268435456 (256.0MB)
G1HeapRegionSize = 0 (0.0MB)
Heap Usage:
New Generation (Eden + 1 Survivor Space):
capacity = 966393856 (921.625MB)
used = 57484824 (54.821800231933594MB)
free = 908909032 (866.8031997680664MB)
5.94838467184957% used
Eden Space:
capacity = 859045888 (819.25MB)
used = 50165232 (47.84129333496094MB)
free = 808880656 (771.4087066650391MB)
5.839645204145369% used
From Space:
capacity = 107347968 (102.375MB)
used = 7319592 (6.980506896972656MB)
free = 100028376 (95.39449310302734MB)
6.818565955528846% used
To Space:
capacity = 107347968 (102.375MB)
used = 0 (0.0MB)
free = 107347968 (102.375MB)
0.0% used
concurrent mark-sweep generation:
capacity = 2147483648 (2048.0MB)
used = 276183376 (263.3889923095703MB)
free = 1871300272 (1784.6110076904297MB)
12.860790640115738% used
Perm Generation:
capacity = 268435456 (256.0MB)
used = 85506216 (81.54508209228516MB)
free = 182929240 (174.45491790771484MB)
31.85354769229889% used
34698 interned Strings occupying 3779016 bytes.
最终的解决方案通过降低内存分配解决。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于