1.如果服务可以本地启动那么尽量在本地进行参数预估
2.如果服务不能本地启动,可以使用远程连接方式进行预估
3.衡量要点:
Java程序运行大致分为三块:堆内存,非堆内存(虚拟机栈,方法区,本地方法栈,程序计数器),堆外内存.
docker容器中运行除了Java程序还需要为其余程序余力内存空间.这里假设统一预留50M空间.
3.1 堆内存的量化
堆内存主要分为几个区域,新生代,复制区,老年代.考虑GC会大量回收堆内存空间,只要不发生内存逸出和内存
泄露情况,堆内存能支持一定的并发即可.无线上数据参考情况可以,简单预估QPS为3进行测试堆内存可能大小.
这里以POIService为例子,启动项目后连接后观察情况如下.
访问接口调用时,其各项数据.
图中可以看出 堆内存最小可以到50M最大可大300M左右,堆内存主要用于实例化对象.我们这里预估下 150M就够用了.
为了线上稳定再次基础上提升10%, 可配置固定内存大小为165M即参数 -Xmx165M -Xms165M
线程没有及时进行回收,导致线程量一直在增加.需要优化相关代码.不然会导致线程占用内存持续增加,JVM会为每个线程单独
分配空间.
3.2 非堆内存量化
图中可以看出,非堆内存使用量不是很大大概65M左右.
设置参数:-XX:PermSize=65M -XX:MaxPermSize=130M (1.8以前)
-XX:MetaspaceSize = 100M (1.8以后)
这里预估为 165 + 100 + 20(对外内存) + 50 = 335M 这里直接给400M
这里要说下.因为资源有限才这么设置,如果资源足够可以进行GC时间的衡量来设置相关参数.
-Xmx180M -Xms180M -XX:MaxDirectMemorySize=20M -XX:MetaspaceSize=100M
调整后效果还可以,这里主意,GC会导致STW可能影响响应时间,要去衡量那个是当前需要的.
远程调试尝试
远程连接配置如下:
[program:configservice]
command=java -Xmx180M -Xms180M -XX:MaxDirectMemorySize=20M -XX:MetaspaceSize=100M -Djava.rmi.server.hostname=106.75.105.45 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=19999 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -jar -Dfile.encoding=UTF-8 configservice.jar
没有限制前top观察到内存使用快到1G了,限制后如下:
一天后再次观察数据如下:
还是比较稳定的,目前使用内存 350M左右.线上给400M.