最近几天线上服务器内存一直报警,物理内存持续超过 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.
最终的解决方案通过降低内存分配解决。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于