严重的番石榴内存泄漏-需要解决方法 [英] Critical guava memory leak - Workaround needed

查看:154
本文介绍了严重的番石榴内存泄漏-需要解决方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有什么方法可以解决 Google Guava r15 内存泄漏(指向错误报告的链接)?

Is there any way to workaround the Google Guava r15 memory leak (link to the bug report) in the cache component?

(不依赖于应用程序服务器可能会清理内容和/或考虑到Web应用程序将永远不会重新启动/重新部署)

(Without relying that the application server might clean things up and/or considering that the web application will never be restarted/redeployed)

推荐答案

我猜你不需要关心它. Tomcat消息说

I guess you don't need to care about it. The Tomcat message says

线程将随着时间的流逝而更新,以尝试避免可能的内存泄漏.

Threads are going to be renewed over time to try and avoid a probable memory leak.

IIUIC意味着一旦所有旧线程都消失了,指向该类旧版本的所有指针也将消失.

IIUIC it means that once all old threads are gone, so will all the pointers to the old version of your class.

详细信息:进行线程池化的原因是创建线程的成本很高.当您得到一个正在做其他事情的线程并且线程不是无状态的时,池本身是很糟糕的.假设您需要大量线程并且永远不要回收它们,则线程创建的成本很高.每隔几分钟更新所有线程并没有错,所以我希望Tomcat的解决方法能够完美解决它. 但事实并非如此.

Details: The reason for the thread pooling is the big cost of thread creation. The pooling itself is hacky as you get a thread which was doing something else and thread are not stateless. Thread creation is expensive assuming you'd need a lot of them and never recycle them. There's nothing wrong with renewing all threads every few minutes, so I hoped, Tomcat's workaround solves it perfectly. But it's not the case.

恐怕我误会了一些东西.链接的错误说

I'm afraid, I misunderstood something. The linked bug says

似乎使用guava缓存的Web应用程序可能会遇到内存泄漏. 重新部署几次后,应用程序容器因OutOfMemoryError崩溃或停顿.

It seems that web applications which are using guava cache might face a memory leak. After several redeployments, the application container crashes or stalls with an OutOfMemoryError.

我认为Tomcat可以轻松解决它,但是无论出于何种原因,它都无法解决.因此,恐怕您必须自己清洁ThreadLocal.通过反射很容易做到这一点,相关的字段是Thread.threadLocals,可能是inheritableThreadLocals.这是一个很糟糕的技巧,更难的部分是在没有错误的情况下(例如,在没有应用程序加载的情况下)使这种情况发生.

I thought Tomcat could solve it easily, but for whatever reason it doesn't. So I'm afraid, you have to clean the ThreadLocals yourself. This is easily possible via reflection, the concerned fields are Thread.threadLocals and possibly inheritableThreadLocals. It's a bad hack and the harder part is to make this happen when nothing can go wrong, i.e., when no application is loaded.

我想这样做是安全的

Stripped64.threadHashCode = new ThreadHashCode();

因为所包含的内容仅在激烈争用时才需要性能,它们在使用后会被重新创建. 但是根据MRalwasser的评论,它完全没有帮助,因为活动线程仍然会引用旧值.所以似乎没有办法.

as the contained things are only needed for performance under heavy contention and they get recreated upon use. But according to MRalwasser's comment, it won't help at all as alive threads will still refer the old value. So there seem to be no way.

由于ThreadLocal通过使用线程存储数据(而不是使用实际的Map<Thread, Something>)来工作,因此您必须遍历所有线程并删除那里的引用.愚弄其他线程的私有字段是一个糟糕的主意,因为它们不是线程安全的,并且也是由于可见性问题造成的.

As ThreadLocal works by storing data with the threads (rather then using a real Map<Thread, Something>), you'd have to through all threads and remove references there. Fooling around with other threads' private fields is a terrible idea as they are not thread-safe and also due to visibility issues.

我可能对

Another thing that might or mighn't not work is my proposal on the issue page. It's just a 20 line patch. Or simply wait, the issue has been assigned yesterday.

不使用的线程局部语言不会引起任何问题. AFAIK此TL的唯一用途是在缓存统计信息中.因此,请避免同时加载CacheBuilder.recordStatsCache.stats以及Stripped64.

Thread locals which don't get used can't cause any problems. AFAIK the only use of this TL is in cache stats. So avoid both CacheBuilder.recordStats and Cache.stats and Stripped64 won't get loaded.

看来终于可以解决了.从问题:

It looks like it's gonna get fixed finally. From the issue:

Doug为我们修复了上游问题,我们将其修补回了Guava: http://gee .cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/Striped64.java?revision = 1.9

Doug fixed this upstream for us and we patched it back into Guava: http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/Striped64.java?revision=1.9

乍一看他的更改似乎与最后,它已被标记为固定并且番石榴18.0-rc1 已宣布.鉴于更改与我的更改相同(9个月前),花了这么长时间,这实在令人遗憾.

Finally, this has been marked as fixed and Guava 18.0-rc1 has been announced. It's just sad it took that long given that the change is the same as mine (9 month ago).

这篇关于严重的番石榴内存泄漏-需要解决方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆