【发布时间】:2018-10-10 02:34:00
【问题描述】:
是否可以从 gc 的角度将 java 对象标记为不可收集以节省 gc 扫描时间?
类似于http://wwwasd.web.cern.ch/wwwasd/lhc++/Objectivity/V5.2/Java/guide/jgdStorage.fm.html 的东西,特别是非垃圾收集容器(非垃圾收集?)。
问题是我有很多普通的临时对象,但我有更大(几个 Gigs)的对象存储用于缓存目的。 Java GC 不应该无缘无故地遍历所有那些试图找到任何要收集的缓存千兆字节,因为它们包含有自己的超时的缓存数据。
通过这种方式,我可以以自定义方式将我的数据划分为无限生命和正常生命的对象,并且希望 GC 会很快,因为普通对象的生命不会那么长并且数量较少。
有一些解决这个问题的方法,例如Apache DirectMemory 和 Commercial Terracotta BigMemory(http://terracotta.org/products/bigmemory),但是 java-native 解决方案会更好(我的意思是免费的,可能更多可靠的?)。另外我想避免序列化开销,这意味着它应该发生在同一个 jvm 中。据我了解,DirectMemory 和 BigMemory 主要操作堆外,这意味着对象必须在 jvm 外部的内存中序列化/反序列化。简单地在 jvm 中标记非 gc 区域似乎是一个更好的解决方案。使用文件进行缓存也不是一种选择,它具有相同的无法承受的序列化/反序列化开销 - 用例是 HA 服务器,其中大量数据以随机(人工)顺序使用并且需要低延迟。
【问题讨论】:
-
是什么让您认为 BigMemory 不是 Java 原生的?听起来您真正的意思是免费。
-
您可以自己使用直接内存来缓存数据(堆外)我这样做是为了保持 100 GB 的堆外空间。
-
@PeterLawrey 自己使用直接内存不是一个选项,因为我想避免序列化开销,这意味着它应该发生在同一个 jvm 中。
-
@MattBall 是的,最好是免费的并且(本机,单个 jvm)没有序列化开销。
-
@MarkoTopolnik 当我知道内存快用完时,也许我可以有一个指示器,以清除一些缓存......嗯......