使用副本跟踪任何Java对象中的更改

时间:2016-06-30 02:32:41

标签: java object serialization garbage-collection

我正在研究Java中的序列化函数,理想情况下应该使用任何实现接口的类(类似于Serializable)。作为其中的一部分,我想跟踪自动实现序列化界面的对象的更改。为了做到这一点,我试图克隆最后写入的对象 - 从持久性和内存中读取时只有更改版本。但是,我无法想出一个正确的方法来在两个(原始的和改变的)对象之间建立一个不会消耗大量内存的对象。到目前为止,我已经考虑过几种方法来解决这个问题:

  1. 将成员添加到引用原始版本克隆的更改的对象类/超类中,以便每次写入更改的对象时,编写者都可以访问原始文件并计算差异。但是,这需要使用继承来正确完成,这对此来说是不好的形式,特别是考虑到Java只允许一个超类(当我们想要对扩展其他东西的对象执行序列化时会发生什么?另外,它不一定会使语义意义上的问题"是一个允许它被序列化的东西。这不能通过接口来实现(接口,当然,不允许声明变量)。
  2. 有某种链接数据结构 - 可能是某个地方的静态地图。这会失败,因为链接结构将始终具有对已更改对象的引用,这可防止它在垃圾回收中被释放,即使代码的操作部分早已取消引用该对象。也许有一些方法可以创建一个垃圾收集器没有看到的引用 - 也许是Java哈希?
  3. 在运行时以某种方式将克隆的原始文件作为动态成员(可能是私有/隐藏)添加到已更改的副本中,可能使用反射。这似乎是非常糟糕的形式,但只会添加一个引用,只能从更改的版本到原始克隆,这意味着没有GC问题(原始克隆没有任何引用,而不是来自更改版本)假设GC将检测从改变的参考到原始参考。
  4. 我在这里缺少其他明显的东西吗?有什么方法可以解决上述问题吗?

1 个答案:

答案 0 :(得分:1)

由于似乎没有更好的方法,我将编写一些代码来自动扩展要序列化的对象的类。新的子类将克隆作为成员,但除序列化代码外,将被视为超类。我从中看到的唯一冲突来自Object.getClassName()及其相关功能(instanceof)。也许我可以想出一种覆盖getClassName方法的方法。我希望有一种更简单的方法来获得这种透明度。