JVM虚拟机有自己的垃圾回收机制,一般情况下无需担心内存溢出的问题。但不是绝对的无需担心。
最近遇到一个服务器内存溢出问题,起因是使用了一个永不会关闭的线程,去做PDF上传下载,程序能正常运行一周,然后内存溢出。每日增量增加80多MB内存,并不会被GC回收。
内存溢出一般可能存在的情况:
1、实例化对象太大,超出空闲内存
2、读取文件等操作,一次加载全部,全加载到内存,超出内存范围
3、静态域做缓存,静态变量不会被GC机制处理,即使内存溢出
4、大量无效强引用对象,GC不会处理强引用对象,可达性算法也不会标记活跃对象。
取样查看内存使用情况
jstat -gcutil 28506(pid) 1000 5 间隔一秒,取五次
jmap查看是否有jmap环境
生成jvm快照
jmap -dump:live,format=b,file=xx.hprof 28506(PID)
报以下错误:在语句中加-F
Unable to open socket file :target process not responding or hotspot vm not loaded
the -F option can be used when the target process is not responding
jmap -F -dump:live,format=b,file=xx.hprof 28506(PID)
在内存溢出前生成JVM快照配置
启动脚本中加
export JAVA_OPTIONS="-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/local/app/oom";
nohup $JAVA_OPTIONS -jar xxxx &
java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/local/app/oom -jar xxx