Tooster
Tooster

Reputation: 442

Hypothetical partial object dealocation in java

The following is a hypothetical problem. I'm purely interested if the effect is SOMEHOW achievable, by any obscure means imaginable (unsafe API, JNI, ASM etc). It is not an XY problem and I don't ever plan to write code like that! I'm just curious about internals.

Let's assume that we have this very simple hierarchy in 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";
    }
}

Our process is as follows:

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

Putting it into words:

  1. We create an object of subtype, that has a lot of memory allocated.
  2. We perform some internal state transformation on this subtype object.
  3. We upcast the object to it's supertype and from now on we will ONLY refer to it by it's supertype and never downcast

So now our JVM holds a Cupcake reference to an internal WholeRealityItself object with memory that (the programmer knows) will never again be accessed. Yes, I know that references and actual allocated objects are two different things and upcasts/downcasts make the program just "reinterpret" an object.

Completely ignoring the fact that this abomination of a code is unusable and should be replaced with a sane builder/factory/copy or whatever, just assume for the sake of argument that we want it that way. The point is not how to achieve the same effect but if the following is possible:.

Can you force a narrowing of the actual allocated OBJECT to covert it's internals to a Cupcake from WholeRealityItself and force deallocation of wholeMatterOfUniverse?

AKA - can you SOMEHOW slice an underlying allocated OBJECT? Last questions about object slicing are from ~10 years ago.

Upvotes: 1

Views: 114

Answers (3)

Stephen C
Stephen C

Reputation: 719336

AKA - can you SOMEHOW slice an underlying allocated OBJECT?

No you can't.

The object is represented by a heap node. If you did anything to interfere with the size or type (class) of the heap node, you are liable to crash the garbage collector.

I guess, you could use abstraction breaking (nasty!) reflection to identify and assign null to all of the fields added by the subclass. But the problem is that you can't do anything about methods of the superclass that the subclass has overloaded. If those methods refer to any of the fields that you have assigned null to, and something calls them, you have a potentially broken (smashed) object.

My advice: create a brand new Cupcake object using the relevant state from your WholeRealityItself object. It will have a different reference. Deal with that.

This David Wheeler quotation may be relevant ...

"All problems in computer science can be solved by another level of indirection."

Upvotes: 3

Thomas Kläger
Thomas Kläger

Reputation: 21610

Neither upcasts nor downcasts change the object itself - they only influence how the compiler treats the reference to the object.

One example are overriden methods: what method is called depends entirely on the runtime type of the object, not on the reference type that the compiler uses:

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() {
         //...
    }
}

After your sample code

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

the call cupcake.printMeOut(); will print out "WholeRealityItself" every time now matter how much time passed since the upcast.

Upvotes: 1

gfelisberto
gfelisberto

Reputation: 1723

You are talking about upcasting and nothing happens to your object. Only way to free would be to have a constructor in cupecake that would take another cupecake as input and would only use the needed parts. After you would release wholeworld.

Upvotes: 0

Related Questions