我正在监视一个长时间运行的java进程,该进程使用g1垃圾收集器。
这些是我的java选项(在服务器模式下运行):
-Xmx2048m -XX:+UseG1GC -XX:+UseStringDeduplication -XX:G1HeapRegionSize=32M -XX:MetaspaceSize=100m -XX:CompressedClassSpaceSize=400m
该进程是一个javawebsocket服务器,它包含大量的i/o,前面嵌入了tomcat。根据java任务控制,顶层堆的使用率达到了1.7gb,在每个gc周期之后,它会减少到900mb。该进程在具有3.8gb内存限制的docker容器中运行。使用时 top -o %MEM
它表明,总的res是2.6gb,从来没有超过。
我注意到,在大量的websockets连接/断开连接之后,这个过程变得非常缓慢和无响应。
当我尝试在6-7小时后再次加载此进程时,当它处于空闲状态并且“清除”连接时,它会在6-7秒后响应,而在第一次加载时,响应时间要低得多~2-3秒。
我以为是文件描述符相关,但在检查时:
ls /proc/1/fd | wc -l
从docker内部显示所有释放的文件描述符。
java版本:8u131 tomcat版本:8.5.60
这是我的堆在服务器上没有连接的情况下加载6小时后的样子:
这是jmc发来的:
我如何进一步调查?
1条答案
按热度按时间ufj5ltwl1#
不要把重点放在内存和垃圾收集上,但要确定在请求处理过程中需要花费的时间。在请求处理程序代码中花费的时间是多少?它在别的地方吗?
如果可以修改代码,只需添加一些println语句即可。和/或您可以使用像https://github.com/jvm-profiling-tools/async-profiler 为了得到一个cpu火焰图-墙壁时钟配置文件可能特别有助于“离开cpu”的分析。