1

我的问题与不同,我对我的应用程序进行了分析,它太慢了。
完成一个过程后,我在堆遍历器中看到了一些活动对象。

虽然我们正在将一些数据从数据库缓存到,HashMap但堆步行器向我展示了一些活动对象Resultset.getString,例如Statement.getString不应该存在的对象。

HashMap.put()与上述两种方法相比,占用的内存要少得多。

我做的一切都很好吗?这个分析对吗?或者我遗漏了任何东西,内存被HashMap自己占用,HeapWalker只是向我展示了 JDBC(getStringexecuteQuery)的方法。

4

2 回答 2

2

既然您在谈论方法,我猜您正在查看堆步行器的“分配”视图。该视图显示创建对象的位置,而不是引用对象的位置。有一个屏幕截图解释了 JProfiler 中的分配记录

HashMap.put不会分配大量内存,它只会创建用于存储键值对的小型“条目”对象。占用大量内存的对象是在将它们放入哈希映射之前创建的。

Resultset.getStringStatement.getString创建从数据库中读取的 String 对象。因此,可以合理地假设其中一些对象的寿命更长。

要找出对象仍在堆上的原因,您应该转到引用视图,选择传入的引用并搜索“到 GC 根的路径”。“最大对象”视图对于追踪过多的内存使用也非常有帮助。

于 2012-02-23T13:21:13.490 回答
1

您可能看到的是连接(可能是其缓冲区缓存)或语句或结果集所保存的缓存数据。

这可能是因为没有关闭连接、语句或结果集,也可能是由于连接池。如果您查看内存配置文件,您可能会看到“到 GC 根目录的路径”(对象根目录的路径),这将表明是什么保存了您的ResultSet字符串。您应该查看它是否在您的代码中,是否缓存在您保留的内容中,或者是否在池中。

注意我没有使用过 JProfiler ,但这就是我使用YourKit跟踪它的方式。

于 2012-02-23T09:10:39.667 回答