私有方法调用的垃圾收集
我的 java 应用程序中存在内存使用问题,我一生都无法理解为什么垃圾收集器没有对其进行排序。代码如下:
public void foo() {
for(int i=0; i<50000; i++) {
bar(i);
}
}
private void bar(int i) {
LargeObject o = new LargeObject();
...
dao.save(o);
}
我的问题是 LargeObject 的实例没有被垃圾收集 - 为了识别这一点,我使用 jprofiler 进行了分析并查看了堆。 LargeObject 实例永远不会被类变量引用,事实上,它们不会在 bar()
之外的任何地方被引用。我觉得我抓住了救命稻草,但这可能与交易开始/结束的位置有关吗?我尝试将 bar()
更改为 public 并使用 Propogation.REQUIRES_NEW
进行注释,并将 foo()
上的注释更改为 Propogation.NEVER
无济于事。
dao 内的代码如下所示:
public void save(LargeObject o) {
hibernateTemplate.getSessionFactory().getCurrentSession().saveOrUpdate(o);
}
垃圾收集肯定会运行,正如我在 jprofiler 中看到的活动一样。 foo()
大约需要 30 分钟,bar()
需要 36 毫秒,垃圾收集大约每 60 秒出现一次峰值。
为了回答为什么我确定它们没有被垃圾收集的问题 - 系统中没有任何内容引用 LargeObject,但我看到它们在堆上的实例随着 foo() 的执行而增加。
I have a problem with memory use in my java app and for the life of me I can't understand why the garbage collector isn't sorting it out. The code is as follows:
public void foo() {
for(int i=0; i<50000; i++) {
bar(i);
}
}
private void bar(int i) {
LargeObject o = new LargeObject();
...
dao.save(o);
}
My problem is that instances of LargeObject are not getting garbage collected - to identify this I've profiled with jprofiler and looked at the heap. LargeObject instances are never referenced by class variables, in fact they're not referenced anywhere outside of bar()
. I'm clutching at straws I feel but could this be related to where the transactions start/end? I've tried changing bar()
to public and annotating with Propogation.REQUIRES_NEW
and also changing the annotation on foo()
to Propogation.NEVER
to no avail.
The code inside the dao looks like this:
public void save(LargeObject o) {
hibernateTemplate.getSessionFactory().getCurrentSession().saveOrUpdate(o);
}
The garbage collection definitely runs as I see it's activity in jprofiler. foo()
takes about 30 mins, bar()
takes 36ms, garbage collection spikes roughly every 60 secs.
To answer the question why I know for sure they're not being garbage collected - nothing in the system references LargeObject yet I see instances of them on the heap increasing as foo()
is executing.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
显然,它们是由您的 JPA 提供程序(或隐藏在
dao.save()
后面的任何内容)引用的。您确实将引用放在外面,因此您失去了对它的控制。无论您使用私有/公共方法执行此操作并不重要。您可能想分享有关此“DAO”的更多信息。
Apparently they are referenced by your JPA provider (or whatever is hiding behind the
dao.save()
). You do let the reference outside, hence your control over it is lost. Whether you do it in a private/public method does not matter.You might want to share more information about this "DAO".
我要补充@MaDa的答案,即循环可能会给必须缓存所有
大对象
实例的唯一会话带来负担。您应该考虑:保存后刷新会话,或者使用新会话,或者为每个LargeObject
清除会话(如果它们不相关)阅读 批处理 可能会帮助您理解您的问题
I'd add to @MaDa's answer that the loop might cause the burden on the unique session that had to cache all the
Large Objects
instances. You should consider either : flushing the session after save, or use a new session, or a cleared session for eachLargeObject
If they are not relatedReading the section on Batch Processing may help you understand your problem