1.使用top命令查看内存使用最高的应用

查询当前java程序运行所占用内存 java查看进程占用内存大小_linux


使用大写M可按照内存使用排序,大写P可按cpu使用排序;

可以看到第一个java应用占用的cpu和内存明显高于其他几个;

2.定位线程问题

使用top查看第一个线程19503的线程情况

命令:top -Hp 19503

查询当前java程序运行所占用内存 java查看进程占用内存大小_查看java进程当前应用的配置文件_02


可以看到19503 这个pid应用产生了很多的线程;

3.查看内存使用的堆栈信息

使用jstack命令查看

将pid为19503 的应用打印到日志中

[root@localhost ~]# jstack -l 19503 > jstack_19503.log

4.查看内存堆栈信息

[root@localhost ~]# more jstack_19503.log

查询当前java程序运行所占用内存 java查看进程占用内存大小_linux_03


发现大量线程状态为WAITING的

parking to wait for  <0x00000000e7e54130>

存在大量线程等待被唤醒,占用大量内存。

当然,其中原因可能不止这个,也可能发生死锁等情况,可以根据具体情况分析自己的代码,再根据实际情况优化修改;

补充:这里说一下使用jstack命令时遇到的异常情况:

1.登录用户和应用所属用户不一致:

19503: well-known file /tmp/.java_pid19503 is not secure: file's group should be the current group (which is 1000) but the group is 0

这个可能是由于应用的所属用户和当前用户不一致引起的,切换为应用所属用户即可

可以通过这个命令查看所有java应用的信息:

ps -ef | grep java

2.jstack无法连接jvm

19503: Unable to open socket file: target process not responding or HotSpot VM not loaded

看到网上很多解答说是因为:这个java进程的pid文件删除了。

由于linux操作系统为了防止/tmp目录文件过多,有个删除管理机制:tmpwatch;

系统每天会用tmpwatch命令检查并删除 /tmp 下超过240小时未访问过的文件和目录。

具体解决办法:https://blog.51cto.com/zhangshaoxiong/1310166

但是感觉修改较为复杂,且需要修改到系统文件,所以我这边使用了一个临时方法,在启动jar包时加一个命令指定一个临时文件夹即可:

java -Djava.io.tmpdir=/tmp/tmpdir -Dfile.encoding=utf-8 -Xmx512m -jar test.jar --spring.profiles.active=test

其中的-Djava.io.tmpdir=/tmp/tmpdir命令增加的指定命令,/tmp/tmpdir为指定文件夹位置。