我如何有效地缓的对象,在Java使用可用RAM?
-
23-09-2019 - |
题
我需要高速缓冲的对象,在Java使用一定比例的任何RAM。我知道,其他人有问这个问题,但没有任何答复符合我的要求。
我的要求是:
- 简单的和轻便的
- 不大大慢于一个普通的哈希
- 使用LRU,或删除一些政策,近似于LRU
我试图LinkedHashMap,但是它需要指定一个最大数量的元素,并且我不知道该如何许多要素,它将需要填补了提供RAM(它们的大小会明显不同).
我目前的做法是使用谷歌收集是制图师如下:
Map<String, Object> cache = new MapMaker().softKeys().makeMap();
这似乎是有吸引力,因为它应当自动删除元素的时候,就需要更多的RAM,但有一个严重的问题:它的行为是以填补所有可用RAM,在这一点的GC开始鞭打和整个应用程序的业绩恶化显着。
我听说过这样的东西里,但它似乎相当繁重的体重为什么我需要,我不确定如果它是足够快的我的程序(记住的是,该解决方案不能被大大慢于哈希).
解决方案
我已经有了相似的要求,向你并发(2hexacore Cpu)和LRU或类似的-也尝试过的番石榴制图师.我发现softValues()远远低于weakValues(),但既使我的应用程序的速度奇慢,当存储器中填充的。
我试图WeakHashMap它是不成问题,奇怪的是,即使速度比使用LinkedHashMap作为一个LRU高速缓冲存储器通过其removeEldestEntry()方法。
但对我来说是最快的 ConcurrentLinkedHashMap 这使得我应用程序3-4(!!) 倍的速度比任何其他缓我尝试。欢乐,后天的挫折!它的显然已被纳入番石榴的制图师,但LRU特征是不是在石榴r07在任何速度。希望这对你的作品。
其他提示
我已经实现薮缓存,而且它可能为困难,因为执行一个新的数据源或线程池,我的建议是使用boss-高速缓冲存储器或另一个众所周知的缓存lib。所以你会睡得好没有问题
我听说过这样的东西里,但它似乎相当繁重的体重为什么我需要,我不确定如果它是足够快的我的程序(记住的是,该解决方案不能被大大慢于哈希).
我真的不知道如果一个可以说, 里 被重重。至少,我做不考虑拖如此,尤其是当使用 存储器中存储 (这是支持一个扩大的 LinkedHashMap
并且当然是最快的缓存的选择)。你应该给它一试。
我相信 MapMaker
会是唯一合理的方式得到什么你要求。如果"的GC开始鞭打和整个应用程序的业绩恶化显着,"你应该花一些时间来适当地设定各种调整参数。这份文件可能看起来有点吓人,但它实际上写得很清楚,是一个金矿的有用的信息有关GC:
http://java.sun.com/j2se/reference/whitepapers/memorymanagement_whitepaper.pdf
我不知道,如果这将是一个简单的解决方案,特别是比里或类似的,但是你看过的 Javolution库?它不是专为如此,但在 javolution.context
包他们有一个分配模式,可以重复使用的对象而不需要垃圾收集。这样,他们保留对象的创建和垃圾的收集到最小,一个重要特征,用于实时程序。也许你应该看一看并且试图使其适应你的问题。
使用现有的高速缓存,储存WeakReference而不是通常的对象refererences.
如果GC开始运行的自由空间,值举行的WeakReferences将被释放。
你不能"删除元件"你只能停下来硬的参考它们,并等待GC清理他们,因此与谷歌的收藏...
我不知道还有一个简单的方法,以找出对象的大小。因此,我不认为你会找到方法来限制一个数据结构的内存数量它的考虑。
基于这一假设,你坚持限制的数量缓存的对象。我建议运行模拟的一些现实生活中的使用情况并收集统计数据的类型的对象,进入缓存。然后你就可以计算出的统计平均大小和数量的目的,你可以负担得起的高速缓存。虽然这只是一个近似数量的RAM你想要全身心地投入到缓,这可能是不够好。
为缓执行,在我的项目(一个关键性能的应用),我们正在使用里,并亲自我找不到它的重量级。
在任何情况下,运行几项测试与几个不同的配置(关于尺寸,驱逐的政策等)。 和找出什么对你最好的。
缓存的东西, SoftReference
也许最好的方式,直到现在我可以想象的。
或者你可以重新改造的对象-游泳池。每个对象你不用,你不需要要摧毁它。但它来保存CPU而不是保存记忆
假设你想缓存线的安全,那么你应该审查的高速缓冲例如在布莱恩戈茨书"Java并发在实践"。我不能让这种高度不够。