1

I'm looking for a way to delete an object in Java, make it eligible for GC. I have a Java class that needs to have its delete() method called.

public class SomeObj {

    // some implementation stuff
    //...

    void delete() {
        //remove yourself from some lists in the program
        //...

        this = null; // <- this line is illegal

        //delete this; <- if I was in C++, I could do this
    }
}

How should I do this? Apparently, I'm going to have to refactor my code because this smells like bad design.

Doga Oruc
  • 783
  • 3
  • 16
  • 4
    You simply cannot do this in java. As soon as nobody references your object anymore it will *at some point* get deleted and you will not know for sure if and when that happens. – luk2302 Sep 04 '20 at 13:10
  • It's worth asking why you need to delete a class. Is that because you want to conserve memory? Or because some specific action happens on deletion? And if it's the latter, why not just invoke that action as needed? Over the years, various tricks have been proposed to "help" the GC figure out what can be removed. I'm not sure any of them are very reliable. – Kevin Boone Sep 04 '20 at 13:20
  • @KevinBoone On deletion the object is removed from its owner's, components list. That's what delete should do. Call delete to remove the object from its owner and also delete the object since it's no longer needed. – Doga Oruc Sep 04 '20 at 13:23
  • @Dogo Oruc: if it's no longer needed, there should be no references to it. When it's no longer reachable, GC should deal with it. If GC can't deal with it, that's because it's still reachable. This is, as you said at the start, a design problem. Like it or not, Java runs in a garbage-collecting environment; design needs to be done according to that principle. In situations where that's infeasible, use a different programming language ;) – Kevin Boone Sep 04 '20 at 13:25
  • @KevinBoone is there a way I can get all the references to that object? If I can, I can accomplish the goal of ```delete()``` – Doga Oruc Sep 04 '20 at 13:28
  • @Doga Oruc -- not that I'm aware of, unless your application is already storing that information. But my question stands -- why do you need to do this? What are the implications for leaving the GC to deal with it in its own good time? – Kevin Boone Sep 04 '20 at 13:30
  • @KevinBoone when this object is removed from its owner (what ```delete()``` does in commented spaces), it should no longer exist, it cannot exist without its owner. I'm trying to delete the object so it no longer exists. I know, I can simply call a ```remove()``` method and then set the object reference to null after ```remove()``` returns but I want to have it in a compact way. Like what ```delete()``` does. I believe the question now becomes, "how do I set the calling object's reference to null inside the method?" – Doga Oruc Sep 04 '20 at 13:34
  • I get the expression that your usage of `delete` in c++ is flawed as well. If your object is shared between 10 other different objects and you just delete that object then all objects referencing it will run into problems. It is good that this is not possible in Java. Either other objects still reference it then it will not get deleted or nobody references it anymore after its (sole) owner removes the reference at which point it *may* be deleted, whether or not is actually *is* deleted must not concern you. – luk2302 Sep 04 '20 at 13:36
  • *"how do I set the calling object's reference to null inside the method?"* - **you don't**. And you should not want it, that is not the job of your object, it must not do that. – luk2302 Sep 04 '20 at 13:37
  • There is nothing more compact that "do nothing" :) When an object is no longer reachable, it does not exist in any meaningful way. It's dead to your application, and you don't need to take further action. I'll write a more detailed answer shortly. – Kevin Boone Sep 04 '20 at 13:38
  • @luk2302 the object is not shared, it is tied to an owner, the owner creates that object in its ctor. When the owner wants to remove the object, it calls ```delete()```. This is my use-case. – Doga Oruc Sep 04 '20 at 13:39
  • 1
    Then the owner removes its own reference to the object and be done, end of story. Then the object *may* be deleted and you are done worrying about that instance. – luk2302 Sep 04 '20 at 13:40
  • @luk2302 oh right, I'm a complete moron :D. the owner can just say ```components.get(x).remove()``` instead of ```components.get(x).delete()``` the GC will delete it anyways since the object is not referenced now. Can't believe I'm this blind. Thank you, I can finally stop staring at my screen. – Doga Oruc Sep 04 '20 at 13:42

2 Answers2

1

For better or worse, Java is a language that runs in a garbage-collecting environment. An object has some kind of existence in an application so longer as it is reachable via references. Once it is no longer reachable -- when no other object holds a reference to it -- it is "deleted" so far as the application is concerned.

That the object still has some after-life in the heap is a matter for the garbage collector, not the application. An application that depends on being able to control the existence of objects to which there are no references is broken in some logical sense.

The usual, semi-legitimate reason for wanting to nudge an unreferenced object out of the heap for good is to conserve heap space. There have been many, many occasions when I've known when an object is really finished with better than the garbage collector ever could. Objects that store temporary results with method scope are a good example. I'm primarily a C and C++ developer, and I really want a method on java.lang.Object called ImDoneWithYouNow(). Sadly, it doesn't exist, and we have to rely on the GC implementation to take care of memory management.

Kevin Boone
  • 4,092
  • 1
  • 11
  • 15
  • So, it is impossible to achieve this kind of behavior in Java. Instead of trying to delete an object, have the object removed from where it doesn't need to be and stop worrying about it. GC will handle the deletion. – Doga Oruc Sep 04 '20 at 13:50
  • Yes. Stop worrying about the program, and start worrying about how to tune the GC under load in production ;) – Kevin Boone Sep 04 '20 at 13:51
  • 2
    @DogaOruc it’s not impossible, it’s obsolete. Assuming that you truly do not access the object anymore after the place where you wanted to insert `this = null;`, the object *is* eligible to garbage collection. This has been explained in [this answer](https://stackoverflow.com/a/54942944/2711488) and [that answer](https://stackoverflow.com/a/24380219/2711488). Naive assumptions about scope preventing gc can lead to bugs like [this](https://stackoverflow.com/q/49171990/2711488), [that](https://stackoverflow.com/q/58714980/2711488), or [yet another](https://stackoverflow.com/q/26642153/2711488). – Holger Sep 04 '20 at 15:38
0

You don't need (and really shouldn't have) a "destructor". Once no other object references the object in question, it becomes eligible for garbage collection, and will be removed by the garbage collector when it sees fit.

Mureinik
  • 297,002
  • 52
  • 306
  • 350
  • Yes, what I'm trying to achieve is make it eligible for garbage collection when ```delete()``` is called. I want all the other references to become null as I call ```delete()```. The real question is, is it possible to do this without knowing which objects have a reference to it? Or in a lower level way, is there a way I can get all the pointers that point to a specific location in Java? Since I cannot delete an object right away, I can maybe null each and every pointer pointing to the object. – Doga Oruc Sep 04 '20 at 13:18
  • @DogaOruc There's no way to do this in Java. You can't prevent another object from referencing that object. – Mureinik Sep 04 '20 at 13:19