案例20-内存长期占用导致系统变慢

一、背景介绍

本篇博客是对生产环境出现内存长期占用导致系统变慢的原因分析及总结

现状:

系统出现了爬取加载慢的情况,核心服务的内存占用很高的情况。
如下图:

在这里插入图片描述
在这里插入图片描述

二、思路&方案

查询服务内存占用过高的原因:
1、服务启动时分配的堆内存过小(与Xms和Xmx有关,-Xms 为JVM启动时申请的初始Heap值,-Xmx 为JVM运行时可申请的最大Heap值)
2、具有大量大对象被创建,并且没有及时被GC回收或者由于具有引用GC无法回收(代码中存在不合理的地方,需要进行代码调优)
3、当GC之后,虽然会清理堆内的对象看,但是并不会释放内存,没有把曾经申请到的内存归还给操作系统(与垃圾回收器和垃圾回收器的回收机制有关)

解决方案
1、服务启动时分配的堆内存过小
解决方案:修改启动jar包的时候的配置
如:如:nohup java -Xms3072m -Xmx4096m -jar a.jar&
-Xms 为JVM启动时申请的初始Heap值,默认为操作系统物理内存的1/64但小于1G。默认当空余堆内存大于70%时,JVM会减小heap的大小到-Xms指定的大小,可通过-XX:MaxHeapFreeRation来指定这个比列。

-Xmx 为JVM运行时可申请的最大Heap值,默认值为物理内存的1/4但小于1G,默认当空余堆内存小于40%时,JVM会增大Heap到-Xmx指定的大小,可通过-XX:MinHeapFreeRation来指定这个比例。
在这里插入图片描述
2、大对象被创建但是没有被回收
解决方案:查看代码逻辑存在不合理的地方
方式:我们可以分析dump文件找到内存占用的原因。

首先生成系统快照dump文件:

jmap -dump:[live,]format=b,file=<filename> <pid>

然后通过内存分析工具进行分析:如MAT jvisual
在这里插入图片描述
启动jvisual载入下载下来的.hprof文件,之后就可以进行内存分析了。
+
3、当GC之后,虽然会清理堆内的对象看,但是并不会释放内存,没有把曾经申请到的内存归还给操作系统

解决方案:与垃圾回收器和垃圾回收器的回收机制有关

1、首先jvm明确目前使用的是哪一种垃圾回收器

java -XX:+PrintCommandLineFlags -version

在这里插入图片描述
虚拟机运行在Server模式下的默认值,打开此开关后,使用ParallelSeavenge+ParallelOld的收集器组合进行内存回收。
JDK1.8 默认垃圾收集器Parallel Scavenge(新生代)+Parallel Old(老年代)

1、目前使用的是的是JDK1.8默认垃圾收集器ParallelSeavenge+ParallelOld
2、可以通过修改配置文件的方式,如更换为G1

三、总结

1、写每一行代码的时候都要思考内存占用问题,能不能缩小变量的作用域。
2、启动jar包的时候书写合适的参数,保证程序运行。

四、升华

灰度认知,黑白决策,虽然硬件资源随着摩尔定律的发展成本越来越低,但是这不是我们乱写代码长期占用资源的理由,在看待这个问题的时候我们要对硬件资源成本有一个灰度认知,不能走极端。生活中也是一样,结合现实的不同情况选择不同的方案,用逻辑办事,而不是靠感觉。

内存长期占用导致系统变慢可能是由于内存泄漏或者内存不合理使用引起的。解决这个问题需要以下一些步骤:

内存泄漏检测: 使用工具如内存分析器(如Java中的MAT、Python中的memory_profiler等)来检测内存泄漏。这些工具可以帮助你找到未被释放的内存对象,从而确定是哪些部分导致了内存长期占用。

代码审查: 检查代码,特别是那些与内存管理相关的部分,如对象创建、释放、数据结构的使用等。确保没有未使用的对象或者被遗漏释放的资源。

资源管理: 确保在代码中正确地释放不再使用的资源,如数据库连接、文件句柄等。使用finally块或者资源管理工具来确保资源的正确释放。

缓存和对象池: 如果使用了缓存,确保缓存中的对象可以合理地过期或者被清理。使用对象池来重复使用对象,而不是频繁创建和销毁。

优化数据结构: 使用合适的数据结构,避免使用过于复杂或者低效的数据结构。合理使用集合、映射等数据结构,以减少内存消耗。

分页和分批处理: 如果操作大量数据,尽量采用分页或分批处理的方式,而不是一次性加载所有数据到内存中。

限制资源使用: 如果系统中的某个模块或功能长期占用过多的内存,可以考虑设置资源限制,防止其过度消耗系统资源。

监控和警报: 设置内存使用的监控和警报机制,一旦内存使用超过阈值,及时通知开发人员进行排查和解决。

垃圾回收优化: 针对不同的编程语言,了解其垃圾回收机制,并根据实际情况调整垃圾回收的参数和策略。

水平扩展: 如果系统经常需要大量的内存,考虑进行水平扩展,即增加服务器数量,从而分担内存负担。

定期重启: 在没有找到明显问题原因的情况下,考虑定期重启应用程序,以释放内存和资源。

综合考虑上述方法,你可以逐步定位和解决导致内存长期占用的问题,从而提升系统性能和稳定性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Circ.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值