我的问题与this有所不同。我对我的应用程序进行了分析,结果太慢了 完成一个进程后,我在堆walker中看到了一些活动对象。
虽然我们正在将一些数据从数据库缓存到HashMap
,但堆walker会向我显示一些不应该存在的Resultset.getString
和Statement.getString
等实时对象。
HashMap.put()
占用的内存少于两种方法。
我做得很好,这个分析是对的吗?或者我错过了任何内容,内存被HashMap
本身占用,而HeapWalker
只是向我展示了JDBC的方法(getString
和executeQuery
)。
答案 0 :(得分:2)
既然你在谈论方法,我想你正在看堆walker的“Allocations”视图。该视图显示对象的创建位置,而不是对象被引用的位置。屏幕投射为explains allocation recording in JProfiler。
HashMap.put
不会分配大量内存,它只会创建用于存储键值对的小“Entry”对象。在将它们放入哈希映射之前,会创建占用大量内存的对象。
Resultset.getString
和Statement.getString
创建从数据库中读取的String对象。因此,假设其中一些对象寿命较长是合理的。
要找出为什么对象仍在堆上,您应该转到参考视图,选择传入引用并搜索“GC根路径”。 “最大对象”视图在追踪过多的内存使用量方面也非常有用。
答案 1 :(得分:1)
您可能看到的是连接(可能是其缓冲区缓存)或语句或结果集所持有的缓存数据。
这可能是因为没有关闭连接,语句或结果集,或者可能是由于连接池。如果查看内存配置文件,您可能会看到“GC根路径”(对象根目录的路径),这将指示保留ResultSet
字符串的内容。您应该看看它是否在您的代码中,缓存在您保留的内容中,或者它是否在池中。
N.B。我没有使用过JProfiler,但这就是我用YourKit跟踪它的方式。