在垃圾回收之前对Java对象进行回调

时间:2018-10-26 04:30:15

标签: java caching garbage-collection weak-references finalizer

背景故事:所以我有一个好主意,对吗?有时您正在收集大量数据,并且不需要一直访问所有数据,但是在程序完成之后,您也可能不需要它,并且您实际上并不想搞混数据库表等。如果您拥有一个可以在不使用对象时自动将对象静默地序列化到磁盘,并在需要时以静默方式将它们带回的库,该怎么办?于是我开始写图书馆。它具有许多将对象放置在其中的集合,例如“ DiskList”或“ DiskMap”。它们通过WeakReferences保留您的对象。当您仍在使用给定对象时,它具有对它的强大引用,因此它保留在内存中。当您停止使用该对象时,该对象将被垃圾回收,并且在此之前,该回收会将其序列化到磁盘(*)。当您再次想要该对象时,可以像往常一样通过索引或键来请求它,然后该集合反序列化它(或者,如果还没有被GCd的话,则从其内部缓存返回它)。

(*)现在,这就是症结所在。为了使它起作用,我需要能够在对象成为GCd之前被通知-在不存在其他引用之后(因此无法再修改对象),但是在从内存中擦除对象之前。事实证明这很困难。我曾短暂地以为使用ReferenceQueue可以为我省钱,但是可惜它返回了一个Reference,到目前为止,其引用始终为null。

是否有一种方法,在为对象准备好要进行垃圾回收之后,又是在对其进行垃圾回收之前,已经给它一个任意对象,以通过回调或队列等方式接收该对象?

我知道(Object).finalize()基本上可以做到这一点,但是我将不得不处理不属于我的类,并且我不能合理地覆盖它们的finalize方法。我宁愿不要像自定义类加载器,字节码操作或反射那样神秘,但是如果需要的话,我会这样做。

(此外,如果您知道现有的执行透明磁盘缓存的库,尽管我对此类库的要求相当严格,但我会对此予以青睐。)

1 个答案:

答案 0 :(得分:1)

您可以查找支持“写后缓存”和分层的缓存。值得注意的产品是EHCache,Hazelcast,Infinispan。

或者您可以自己构造一些东西,并带有缓存和空闲时间。 然后,缓存访问将是对象的“用法”。

  

是否有一种方法,在为对象准备好进行垃圾收集之后,再经过垃圾收集之前,是否已经通过任意对象接收(通过回调或队列等)对象?

这严重干扰了垃圾回收。很有可能降低您的应用程序或整个系统的性能。您要做的是在系统内存不足或内存不足时启动磁盘I / O并可能分配其他对象。如果您设法使其工作,那么最终将使用比以前更多的堆,因为在启动GC时必须始终扩展堆。