我在这里遇到一种情况,我们运行的Java EE服务器上部署了多个应用程序。最近,我们经常遇到OutOfMemoryException。我们怀疑某些应用程序可能表现不佳,可能是泄漏,或者其他什么。
问题是,我们无法确定哪一个。我们已经运行了一些内存分析器(比如YourKit),并且它们非常善于告诉哪些类使用最多的内存。但是它们没有显示类之间的关系,所以这给我们留下了这样的情况:我们看到有很多字符串和int数组以及HashMap条目,但是我们无法确定它们是哪个应用程序或包来自。
有没有办法知道这些对象来自哪里,所以我们可以尝试查明分配最多内存的软件包(或应用程序)?
答案 0 :(得分:3)
在这种情况下,有几件事情可以做:
答案 1 :(得分:0)
一个快速的想法是,如果你不介意一些表现权衡,你可能会做一些反思....
答案 2 :(得分:0)
我发现有用的是:
jmap -J-d64 -histo $PID
(删除32位拱的-J-d64
选项)
这将输出如下内容:
num #instances #bytes class name
----------------------------------------------
1: 4040792 6446686072 [B
2: 3420444 1614800480 [C
3: 3365261 701539904 [I
4: 7109024 227488768 java.lang.ThreadLocal$ThreadLocalMap$Entry
5: 6659946 159838704 java.util.concurrent.locks.ReentrantReadWriteLock$Sync$HoldCounter
然后从那里你可以尝试进一步诊断问题,做差异以及不比较连续快照的内容。
这只会暂停VM一段时间,即使对于大堆也是如此,因此您可以安全地在生产中执行此操作(在非高峰时段,希望:):