Spring Boot在一段时间后内存使用率高

6

我有一个部署在数字海洋上的Spring Boot应用程序,我的当前droplet(虚拟PC,命名为droplet)有1GB内存。

我的应用程序有一些cron作业,可以从一些API获取信息并将其存储在数据库中,我将解释一下:

@Scheduled(cron = "50 0 0/12 * * ?")

^ 这个操作会从表格中清除一些数值。

@Scheduled(cron = "50 0 0/1 * * ?")

^ 这个与前面的表格相同,只是针对另一个表格。

@Scheduled(cron = "0 0/1 * * * ?")

有两个这样的程序,从API获取信息,进行一些数学计算,然后将结果存储在数据库中。

从监测工具中可以看到,我的内存使用率从未下降,总是有一点点增长。

它始于大约5个小时前的40%使用率,现在为75%。

有什么方法可以清理内存使用情况吗?也许需要进行垃圾回收?

顺便说一下,我正在使用mysql。

谢谢。

-- 编辑

我刚刚运行了visualvm,结果如下:

分析器: Profiler

监视器: Monitor

看起来垃圾回收确实正在运行,那么问题出在哪里?也许我需要在Digital Ocean设置最大堆大小?


你的cron job在运行什么?另外,你使用的是哪种类型的数据库? - 88jayto
我正在使用MySQL,忘记提到了。我在运行一个对API的GET请求,并根据其他值进行一些数学运算,然后将这些结果保存在数据库中。每分钟大约更新200条记录。 - c0nf1ck
MySQL,很好,你没有使用一些内存数据库(必须确认)。听起来像是内存泄漏,我不认为垃圾回收会对你有所帮助。我建议仔细检查,确保你不会在每次cron作业运行时连续实例化某些重型/长时间运行的东西。 - 88jayto
尝试粘贴实际在这些作业上被调用的代码。 - SSC
1
嗨 - 我在使用Spring Boot中的Cron Job时遇到了相同的问题。我的容器启动时使用了120 MB的RAM,2个小时后现在是140 MB。你能指导一下吗? - Arpan Sharma
2
相关的问题,仍然没有明确的解决方案。 - Digao
4个回答

0
你可以尝试清理实体管理器,因为它会尝试缓存你插入数据库的内容。
entityManager.clear();

我曾经遇到过同样的问题,当时我在几分钟内导入了数百万条记录。在visualvm中,我的结果也非常相似。

因此,在每导入10k条记录后,我清除了实体管理器,这样使用的内存就不再增加了。


0

0

可能是你的Java应用程序或数据库查询需要大量时间,并将DB结果存储在Java堆空间中,这可能是一个问题。

你需要一个更好的分析工具,它不仅告诉你堆使用情况,还指出导致问题的代码。

我个人非常喜欢Appdynamics,因为它可以告诉你代码的所有层面存在的问题。此外,它可供某些用途免费使用并提供SAAS解决方案,非常易于集成。

请看一下它,如果需要更多信息,请让我知道。


0
在现实世界的应用中,资源对于开发人员和公司来说都是宝贵的,因此花费一些钱来增加资源是非常必要的。因此,每个现代应用程序都需要使用最少的内存进行后台工作。@Schedule 是 JVM 中昂贵的注释。我建议您使用 TaskQueues,例如 Celery 和 Redis,而不是使用此注释。您可以在 Redis 中重新排队任务,然后 Redis 发布它们。这对于大型进程和后台进程非常有用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接