java中假设的部分对象释放



以下是一个假设问题。我纯粹感兴趣的是,效果是否可以通过任何可以想象的模糊手段(不安全的API、JNI、ASM等(实现。这不是XY问题,我从来没有计划写这样的代码!我只是好奇里面的东西

让我们假设我们在Java中有一个非常简单的层次结构:

class Cupcake {
public String kind;
// ...
}
class WholeRealityItself extends Cupcake {
public Object[] wholeMatterOfUniverse;
// transform internal state because reasons
public performBigBangAndFluctuateACupcake() {
// ... chaotic spacetime fluctuations produce a cupcake
this.kind = "quantum_with_sprinkles";
}
}

我们的流程如下:

WholeRealityItself reality = new WholeRealityItself();
reality.performBigBangAndFluctuateACupcake();
Cupcake cupcake = (Cupcake) reality; // upcast
// from now on the object will be only accessed via it's supertype and never downcast

用文字表达:

  1. 我们创建了一个subtype的对象,该对象分配了大量内存
  2. 我们对此子类型对象执行一些内部状态转换
  3. 我们将对象上转换为它的超类型,从现在起,我们将只通过它的超型引用它,而从不下转换

因此,现在我们的JVM拥有一个对内部WholeRealityItself对象的Cupcake引用,该对象的内存(程序员知道(将永远不会被访问。是的,我知道引用和实际分配的对象是两种不同的东西,上转换/下转换使程序只是";重新解释";一个物体。

完全忽略了这样一个事实,即这种令人厌恶的代码是不可用的,应该用一个理智的构建器/工厂/副本或其他什么来代替,只是为了论证起见,假设我们希望它是这样的重点不是如何达到同样的效果,而是如果以下情况可能的话:

是否可以强制缩小实际分配的OBJECT,以将其内部从WholeRealityItself隐藏到Cupcake,并强制解除分配wholeMatterOfUniverse

AKA-你能SOMEHOW切片一个底层分配的OBJECT吗?关于对象切片的最后一个问题是大约10年前的问题。

AKA-您能用某种方法对底层分配的OBJECT进行切片吗?

不,你不能。

对象由堆节点表示。如果您做了任何干扰堆节点的大小或类型(类(的事情,那么很可能会导致垃圾收集器崩溃。

我想,您可以使用打破抽象(讨厌!(的反射来识别null,并将其分配给子类添加的所有字段。但问题是,您不能对子类重载的超类的方法采取任何措施。如果这些方法引用了您已将null分配给的任何字段,并且something调用了它们,那么您就有一个潜在的已损坏(已损坏(对象。

我的建议是:使用WholeRealityItself对象的相关状态创建一个全新的Cupcake对象。它将有一个不同的参考。处理好这个。

David Wheeler的报价可能与。。。

"计算机科学中的所有问题都可以通过另一种间接方法来解决">

上转换和下转换都不会改变对象本身——它们只会影响编译器如何处理对对象的引用。

一个例子是overriden方法:调用什么方法完全取决于对象的运行时类型,而不是编译器使用的引用类型:

class Cupcake {
public String kind;
// ...
public void printMeOut() {
System.out.println("Cupcake");
}
}
class WholeRealityItself extends Cupcake {
public Object[] wholeMatterOfUniverse;
@Override
public void printMeOut() {
System.out.println("WholeRealityItself");
}
public performBigBangAndFluctuateACupcake() {
//...
}
}

在您的样本代码之后

WholeRealityItself reality = new WholeRealityItself();
reality.performBigBangAndFluctuateACupcake();
Cupcake cupcake = (Cupcake) reality; // upcast
// from now on the object will be only accessed via it's supertype and never downcast

呼叫CCD_ 10将打印出";整体真实性;现在每一次都很重要,自从上次播出以来已经过去了多少时间。

您正在讨论向上广播,但您的对象没有发生任何变化。释放的唯一方法是在cubecake中有一个构造函数,该构造函数将接受另一个cubecke作为输入,并且只使用所需的部分。之后你会释放整个世界。

最新更新