1、内存过高的原因
1、造成服务器内存占用过高只有两种情况:内存溢出或内存泄漏
(1)内存溢出:
程序分配的内存超出物理内存的大小,导致无法继续分配物理内存,出现OOM报错。
(2)内存泄漏:
不再调用的对象一直占用着内存不释放,导致所占用的这块内存被浪费掉,久而久之,内存泄漏的对象堆积起来,也会导致物理机的内存被耗尽,出现OOM报错。
2、内存监控
(1)visualVM
使用visualVM远程监控运行状态
(使用jconsole也可以监控,这里只介绍jvisualVM工具)
在服务器的jdk的bin目录下创建jstatd安全策略文件,命名为jstatd.all.policy
vim jstatd.all.policy
然后输入配置信息:
grant codebase "file:${java.home}/../lib/tools.jar" {
permission java.security.AllPermission;
};
在服务器中启动jstatd,启动命令
在jdk的bin目录下执行如下命令
./jstatd -J-Djava.security.policy=jstatd.all.policy -J-Djava.rmi.server.hostname=192.168.104.57 -p 22222 -J-Djava.rmi.server.logCalls=true
然后本地输入命令
jvisualvm
打开visualvm工具,添加jstatd连接。即可看到
如果要监控jvm的堆内存变化情况,可以安装visual GC插件 实时监控内存变化。

(2)建立jmx连接
启动参数设置
-Dcom.sun.management.jmxremote.port=12345 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=true -Dcom.sun.management.jmxremote.authenticate=true -Dcom.sun.management.jmxremote.access.file=/usr/local/jmxremote.access -Dcom.sun.management.jmxremote.password.file=/usr/local/jmxremote.password
在目录/usr/local/下增加两个文件jmxremote.access和jmxremote.password
文件内容分别为
jmxremote.access
admin readwrite
jmxremote.password
admin 123456
给两个文件权限
chmod 600 jmxremote.access
chmod 600 jmxremote.password
chown root:root jmxremote.access
chown root:root jmxremote.password
最后通过visualVM建立Jmx连接即可
(3)jstat
使用命令jstat查看内存的使用情况(非图形化界面)
jstat -gcutil 进程id 间隔毫秒数
jstat -gc 进程id
jstat -gcnew 进程id
jstat -gcold 进程id
3、内存使用率过高问题排查
1、oom后分析dump文件:
(1)启动程序时通过指令设置
在启动时添加指令
-XX:+HeapDumpOnOutOfMemoryError
设置后,如果程序OOM,则会生成一个dump文件,通过visualVM打开即可分析,看是那个对象创建过多而导致内存溢出。
(2)、在程序执行的过程中使用jmap指令,保存当前的Dump文件
jmap -dump :file=my_dump_name 进程号
(进程号可以通过jps查看)
然后还是通过visualVM打开,查看dump详情。
(3)、直接用visualVM中的监控-》堆dump,然后查看dump文件。
2、分析oom的原因
观察现象,如果老年代很快就会满了,说明老年代的空间设置的太小了,在启动是配置参数
-Xms3072M : 设置最小堆内存为3G(FullGC达到这个大小就会执行)
-Xmx3072M : 设置最大堆内存为3G(堆内存实际大小)
**堆内存设置太多,FullGC的时间会越久,造成卡顿**
**堆内存设置太小,导致频繁FullGC,造成时常短时间卡顿**
(最大最小值设置相同是为了避免FullGC执行后的堆内存重新分配,减轻伸缩堆大小带来的压力)
(如果线上环境有预热过程,则可以设置为不相等)
-Xmn2048M:设置新生代堆内存为2G(eden区和survival区比例为8:2)(高吞吐的情况下 将eden区尽量设置大些)
-Xss1M:单个线程栈的大小
-XX:MetaspaceSize512M:设置方法区(1.8后元空间)的大小为512M
4、程序中优化内存的点
在代码中需要考虑内存优化的点:https://www.cnblogs.com/iwideal/p/7699527.html
网友评论