内存泄漏 :Java中如果不再使用一个对象,但是该对象仍在GC Root的引用链上,这个对象就不会被垃圾回收器回收,这种情况称之为内存泄漏。大多数是由堆内存泄漏引起的。
少量的内存泄漏可以容忍,但是如果发生持续的内存泄漏,就像滚雪球越滚越大,内存迟早被消耗完,最终结果为内存溢出。但是内存溢出并不只有这一种原因。
内存泄漏的常见场景:
1.大型Java后端应用,处理用户请求后没有及时将用户的数据删除,随着用户请求数量越来越多,内存泄漏的对象占满了堆内存最终导致溢出。内存溢出会导致用户请求无法处理,影响用户使用。重启可以恢复,但一段时间后仍然会内存溢出。
2.分布式任务调用系统进行调度任务时,被调度的Java应用在调度任务结束中出现了内存泄漏,最终导致多次调度后内存溢出。同样重启可以恢复。
解决内存溢出的方法:
Top命令
适合进行初步筛查,看看是哪个进程引起当前CPU利用率比较高
load average:系统负载(即CPU的忙碌时间占比)
total:总内存,free:空闲内存,used:当前使用的内存,buff/cache:缓存(单位均为kB)
下面是每个进程的情况。
VIRT:虚拟内存,无需特别关注
RES:常驻内存,当前整个进程使用了多少内存,重点关注
SHR:共享内,进程在使用时有一些依赖的第三方库,重装系统只需要加载一次就可以在多个进程之间共享,本质上不应该被计算在当前内存里面。但是RES里面包含了SHR,所以计算进程使用内存时需要将RES-SHR,将共享内存排除,剩下的就是当前进程真正使用的内存值了
%CPU:这个进程对CPU的使用率
%MEM:进程使用的内存占用实际可用物理内存的比例
TIME+:当前进程启动以来累计消耗的CPU时间
COMMAND:启动命令
VisualVM:
远程服务器使用: