如何在遗留java应用程序上使用com.opensymphony.oscache查找内存泄漏

如何在遗留java应用程序上使用com.opensymphony.oscache查找内存泄漏,java,memory-leaks,opensymphony,Java,Memory Leaks,Opensymphony,我有一个旧的遗留Java应用程序,它每周运行几次,但速度非常慢,我必须重新启动Tomcat 我检查了New Relic Top事务和错误日志,但我找不到问题的根源,似乎Top事务更多的是一个结果,而不是问题的根源 所以,我想这可能是内存泄漏,我做了一个堆转储,并试图在Eclipse内存分析器上对其进行分析,但我很难识别内存泄漏以及它是否真的是内存泄漏 这表明问题嫌疑人1是com.opensymphony.oscache.web.ServletCache 以下是内存分析器的一些结果: 此外,

我有一个旧的遗留Java应用程序,它每周运行几次,但速度非常慢,我必须重新启动Tomcat

我检查了New Relic Top事务和错误日志,但我找不到问题的根源,似乎Top事务更多的是一个结果,而不是问题的根源

所以,我想这可能是内存泄漏,我做了一个堆转储,并试图在Eclipse内存分析器上对其进行分析,但我很难识别内存泄漏以及它是否真的是内存泄漏

这表明问题嫌疑人1是com.opensymphony.oscache.web.ServletCache

以下是内存分析器的一些结果:

此外,这是VisualVM监视器:

谢谢大家!! 这方面的任何帮助或指导都将非常有用

这是oscache.properties文件:


为了解决这个问题,我建议做几件事

如果您的用例允许您:

在oscache的配置文件中

如果不建议使用磁盘缓存,请尝试减少缓存容量

cache.capacity=1000
请提供oscache的配置详细信息,以便在可能的情况下进行更好的审查

更新

当属性cahce.memory=false时,将使用HashDiskPersistenceListener

我们有两种选择可以尝试

1) 提供缓存容量的值

cache.capacity=1000 #or a value that covers the usecase
2) 使缓存使用磁盘持久性

cache.memory=false

我建议使用YourKit Java Profiler的试用版,它将为您提供有关遗留应用程序代码的更多详细信息。 下面是链接:我在2014年使用这个工具作为一个试用版本,检测基于struts 2和Hibernate的Web应用程序中的内存泄漏


可能是使用
UnlimitedCache
描述的组合+长寿命条目的可能性(不确定在何处配置)允许缓存不绑定地增长,但很少(如果有的话)收缩。无限缓存看起来很有可能,如@AndrewS所示。我认为,对于高流量,缓存可能会造成严重的问题。好的,所以我检查了oscache.properties,我没有cache.capacity的任何配置,默认情况下,我认为它是无限的。这可能是问题的根源之一吗?计算最佳值的最佳方法是什么?定义“最佳”。-)说真的,一切都比一直重新启动Tomcat要好。那么做实验怎么样?您希望向缓存授予多少内存?4 GB对于您的机器来说似乎太多了,那么1 GB怎么样?检查从长远来看,它是否能使应用程序更具响应性,而不会因为缓存未命中而使其速度变慢。如果一切正常,则递归尝试一半大小,直到您开始注意到问题,因为缓存太小。这只是个主意,但我会这么做。谢谢@kriegaex!那很有帮助!但是,如果应用程序目前使用的内存通常超过6GB,那么如果我设置1GB的限制,这会不会对机器造成太大的限制?谢谢!我用oscache.properties文件更新了这个问题。在什么情况下,您认为磁盘缓存不是一个好的解决方案?我将在本周尝试这一点!我只需要找个合适的时间去做,因为这是一个有很多用户的应用程序。从上面的屏幕截图中,您对cache.capacity的第一个猜测是什么?谢谢,我将内存更改为false并添加了cache.capacity。1000对于系统来说是一个非常低的值,现在我有一个25000的缓存容量。这个系统似乎更加稳定。尽管如此,有时我的内存会达到峰值,系统会慢上几分钟,但我不需要重新启动,系统会自行恢复,内存会再次下降。也许微调这个容量限制我可以得到更好的性能。
cache.capacity=1000 #or a value that covers the usecase
cache.memory=false