8

Java has its own garbage collection implementation so it does not require any destructor like C++ . This makes Java developer lazy in implementing memory management.

Still we can have destructor along with garbage collector where developer can free resources and which can save garbage collector's work. This might improves the performance of application. Why does Java not provide any destructor kind of mechanism?

Developer does not have control over GC but he/she can control or create object. Then why not give them ability to destruct the objects?

Abhishek Jain
  • 6,296
  • 7
  • 26
  • 34
  • 6
    Your question has also the answer. Instead of destructor, the java perform the garbage collections – Venkat Apr 09 '10 at 10:13
  • 23
    -1 for unsubstantiated claims on garbage collection. – SteveD Apr 09 '10 at 10:42
  • @stevendick Here I am trying to understand only difference between GC and Destructor. – Abhishek Jain Apr 09 '10 at 10:47
  • 3
    @Abhishek: if that's your only goal, then you should avoid giving such controversive, unsubstantiated claims. – Joachim Sauer Apr 09 '10 at 10:50
  • 4
    "This makes Java developer lazy in implementing memory management" this is complete garbage. You can be just as lazy in C++ when you don't understand what you're doing. Competent developers in Java are capable of managing memory (by preventing leaks) just as well, it just isn't explicitly. – matt b Apr 09 '10 at 11:13
  • 1
    There is a much simpler way to reduce the overhead of object allocation/destruction.. create less objects. Java is optimised to handle short lived temporary objects very efficiently, for longer lived objects the apporach suggested wouldn't make much difference. – Peter Lawrey Apr 10 '10 at 07:05
  • 4
    Just because Java is easier to develop in and has faster time-to-market doesn't mean Java developers are lazy, just more productive. ;) – Peter Lawrey Apr 10 '10 at 07:07
  • -1 biased question. Its a shame, this was lining up to be an interesting question before I found out I was lazy – Richard Tingle Jun 27 '13 at 12:53
  • 2
    your question's negative votes, with a big positive votes for answer earned a gold badge for @Jon Skeet ! – Om Shankar Jun 28 '13 at 13:15
  • @Om: Let's upvote more, so others share the fame – cfi Jul 08 '13 at 18:15
  • See also http://stackoverflow.com/questions/171952/is-there-a-destructor-for-java – Raedwald Apr 23 '15 at 05:54

10 Answers10

55

You're asserting that "garbage collection is very expensive" - could you back that up with evidence? Garbage collection is certainly not free but modern garbage collectors are very good.

Note that one of the ways in which the GC is able to be efficient is that it knows it's the only thing doing memory allocation and deallocation (for managed objects). Allowing a developer to explicitly free an object could hamper that efficiency. You'd also need to worry about what would happen if a developer tried to "use" a freed object:

Foo f = new Foo();
Foo g = f;
free(f); // Or whatever
System.out.println(g.toString()); // What should this do?

Are you proposing that each object should have an extra flag for "has this explicitly been freed" which needs to be checked on every dereference? This feels like a recipe for disaster, to be honest.

You're right though - it does allow Java developers to be lazy in this area. That's a good thing. IDEs allow developers to be lazy, too - as do high-level languages, etc. Laziness around memory allocation allows developers in managed environments to spend their energy worrying about business problems rather than memory management.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I think developers are lazy (in a good way) by nature! – James B Apr 09 '10 at 10:45
  • 27
    `free` isn't *free* either. – Tom Hawtin - tackline Apr 09 '10 at 10:46
  • 1
    @TomHawtin-tackline As one guy said, if something is free it means that you are the product :) – James P. Jun 29 '13 at 01:31
  • 2
    @JamesB "I choose a lazy person to do a hard job. Because a lazy person will find an easy way to do it." - Billus Gatus. – James P. Jun 29 '13 at 01:33
  • 4
    You made a good case that it _allows_ Java developers to be lazy in this area, so they can spend their time on other things. But you didn't answer the part why it is _forbidden_ to willingly, intentionally destruct an object when wanted. – foo Jul 08 '13 at 20:31
  • You got this -1 because developers are developers and not managers. If you say their work is "worrying about business problems", only because their job is programming in a company environment, you are manipulating the meaning of the words. – peterh Jul 01 '14 at 18:08
  • @PeterHorvath: I'm saying their work is "worrying about business problems" in that developers are being paid to achieve a real-world goal - and if using garbage collection allows them to achieve that real-world goal faster than manually managing memory (and I believe it does), then that's a good thing. I don't think that's manipulating the meaning of words at all. I still think about the "business requirements" of code even if it's open source, for example. – Jon Skeet Jul 01 '14 at 18:22
23

Garbage Collection is very expensive.

In fact, for complex applications, the performance of garbage collection is competitive with manual storage management based on malloc / free. There is a classic paper by Benjamin Zorn that clearly demonstrates this. In this paper, Zorn describes how he modified some large heap intensive applications to use a conservative garbage collector instead of malloc and free. Then he benchmarked the original and modified versions of the applications. The result was comparable performance.

This paper was published in Software Practice and Experience in 1993. If you haven't read it, you are not qualified to make pronouncements on the "inefficiency" of garbage collection.

Note that this research was done with a 1993-vintage conservative garbage collector. A conservative collector is mark-sweep without any compaction; i.e. non-garbage objects don't move. The latter means that allocation of space for new objects is as slow and complicated as malloc. By contrast, modern garbage collectors (e.g. Java 6/7 ones) are generational copying collectors which are much more efficient. And since copying compacts the remaining non-garbage objects, allocation is much faster. This makes GC even more competitive ... if one could find a way to do the comparison.


Developer does not have control over GC but he/she can control or create object. Then why not give them ability to destruct the objects?

It depends on what precisely you mean by "destruct".

  • In Java, you do have the ability to assign null. In some circumstances this may hasten the destruction of an object.

  • In Java, you can use finalizers and Reference types to notice that an object is about to be destroyed ... and so something about it.

  • In Java, you can define a close() (or equivalent) method on any object and have it do something appropriate. Then call it explicitly.

  • In Java 7, you have the "try with resources" construct for automatically calling close() on the resources on scope exit.

However, you can't cause a Java object to be deleted NOW. The reason this is not allowed is that it would allow a program to create dangling references, which could lead to corruption of the heap and random JVM crashes.

That is NOT the Java way. The philosophy is that writing reliable programs is more important than efficiency. While certain aspects of Java don't follow this (e.g. threading) nobody wants the possibility of random JVM crashes.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • 2
    @Abhishek: If you were *expecting* an answer which disputed your assertion, why did you include it as an assertion to start with? Why not just ask "Is garbage collection expensive?" That would come over as less argumentative, IMO. – Jon Skeet Apr 09 '10 at 11:39
  • Actually, I'm not *just* disputing the assertion. I'm also providing a reference to hard evidence that (IMO) *disproves* it. – Stephen C Jan 01 '14 at 04:38
  • To the random anonymous downvoter: please feel free to explain why you think this is a bad answer. – Stephen C Jan 28 '14 at 01:27
7

The C++ destructor is not a way to destruct objects - it's a set of operation that are to be done when the object is destructed. In Java you have no control on the time when objects are destructed (they may be even never destructed), so putting any important code to be executed at object destruction is strongly discouraged (although possible - finalize method). If you ask not for a destructor but for a way to explicitly destroy given object, you are inviting dangling references into your code. They are not welcome.

Tadeusz Kopec for Ukraine
  • 12,283
  • 6
  • 56
  • 83
  • 4
    C++ doesn't give you "no control on the time when objects are destructed". C++ uses deterministic finalization. When you delete an object, its destructor is immediately called and then its storage is immediately deallocated. There is no C++ GC. I'm not saying this is necessarily a good thing, but its how C++ works. – Andy Johnson Apr 09 '10 at 10:35
  • 2
    @andyjohnson: Either you misunderstood me or my grammar was broken. Anyway I tried to fix it. No control on the time when objects are destructed is in Java. In C++ you have full control on it (modulo complicated rules about lifetime of temporaries). – Tadeusz Kopec for Ukraine Apr 09 '10 at 10:43
  • @andyjohnson: Storage is immendiately _unavailable_. The actual _deallocation_ may happen later - batch processing is not unheard of. – MSalters Apr 09 '10 at 10:49
  • 1
    @andy Sure there is a Garbage Collector for C++, it's just not standard: http://www.hpl.hp.com/personal/Hans_Boehm/gc/ – fredoverflow Apr 09 '10 at 11:14
5

This makes Java developer lazy in implementing memory management.

No, it releases them to perform useful work.

And Garbage Collection is very expensive.

Compared to what? Facts? Figures? You're about 20 years out of date with that remark. The take-up of Java alone effectively disproves that contention.

This might improves the performance of application.

Or not. Did you have some facts to adduce?

Then why not give them ability to destruct the objects?

Because it's not required?

user207421
  • 305,947
  • 44
  • 307
  • 483
  • "it's not required" Well, how can you ever get your cleanup code called? Java guarantees nothing on finalize(). You can have all the initialisation in the constructor you want, but for cleanup *activities*, Java offers nothing. – foo Mar 16 '12 at 18:16
  • @foo on the contrary. Java offers the finally {} block. – user207421 Mar 17 '12 at 03:34
  • If you insist in verbosity: Java makes no guarantees about the finalize() method, and it has nothing to offer in regard to reliable object destruction. (Yes, at control block level, there is the finally block - which is pretty much useless for the object livecycle.) – foo Mar 22 '12 at 22:27
  • 1
    @foo The answer to your first comment is that you can cause cleanup code to be called in a finally {} block, and this is what Java offers in regard to 'reliable object destruction'. You can't keep pretending that it just doesn't exist. – user207421 Mar 23 '12 at 05:56
  • I don't pretent it doesn't exist, I explicitly acknowledged this exists. But you need to write it again and again, for every block, instead of implementing it just once for the class. For a language that claims to be OO, this is a workaround at best. – foo May 01 '13 at 19:40
  • 1
    @foo Suspect majority of Java programmers have not come across a situation where it is useful to have a destructor. My personal favorite is in logging/tracing where you write code like this: { FN_ENTER(__FUNCTION__); dosomething(); } The FN_ENTER macro creates a new object that causes "Entered " to be logged/traced. When that object goes out of scope, the destructor causes "Exited " to be logged/traced. It saves you having to explicitly call FN_EXIT on exit, and it prevents mismatched logs because even if you return early, the destructor gets called = win. – jarmod Jun 24 '13 at 18:05
  • @foo In the absence of any accepted definition of what constitutes an 'OO' language, or any agreement as to what languages really are 'OO', if any, or any evidence that Java 'claims to be OO' in the sense you intend, whatever that is, your last remark doesn't really mean anything. Your reasoning on the point verges on circular. – user207421 Jun 29 '13 at 01:17
  • @EJP: Java being OO - here is the source: http://www.oracle.com/technetwork/java/intro-141325.html To which definition of OO that may refer to, we could dig into the history of Java (pity they lost the pre- and postconditions, BTW). - While I don't quite see where this argument is going, I refuse the "verges on circular": Java lacks destruction/release control elements for classes. Can we agree on that at least? – foo Jul 02 '13 at 16:14
  • @foo Of course, but it has nothing to do with Java being an OO language. It manifests encapsulation, inheritance, and polymorphism: that's sufficient, by the only formal definition I'm aware of (Wegner 1987). – user207421 Jan 01 '14 at 04:53
4

Destructors are called when the object is destroyed in C++, not to destroy the object. If you want to guarantee cleanup, make the user call a Destroy method or similar.

quantum
  • 3,672
  • 29
  • 51
  • 1
    You cannot *make* the user call a Destroy() method. If you need control to properly release internal resources associated with the object then you need some for of method (like a destructor) that is implicitly called. – jarmod Jun 24 '13 at 18:10
  • @jarmod If the user does NOT call Destroy(), then he leaks a resource. I meant something like `IDispose` in .NET. You call `Dispose()` to explictly dispose an object. – quantum Jun 25 '13 at 21:37
1

If you know you don't some big objects anymore just set the references to them to null. This could maybe speed up the garbage collection of these objects.

Janusz
  • 187,060
  • 113
  • 301
  • 369
  • 2
    Very rarely a good idea, IMO. In most cases the garbage collector is smart enough to work this out for you, and it clutters up your code. There are some exceptions, but they're not very common in my experience. – Jon Skeet Apr 09 '10 at 10:16
  • That is right. In most times you don't need this, but it is a possibility for the programmer who thinks he could trick something out of java to do something like freeing a memory. – Janusz Apr 09 '10 at 10:19
  • It is at least an indication of what you want, even if Java ignores it or optimised it away. And it will make more implementation bugs throw an exception, which is a Good Thing. A speedup of GC is possible, depending on the algorithm the VM implementation uses, but that shouldn't be a reason to do this. – foo Jan 22 '14 at 21:50
1

The C++ destructor is not a way to destruct objects - it's a set of operation that are to be done when the object is destructed.

I think you are confusing terminology. Here is how I see it:

create object = first allocate memory, then construct via constructor

destroy object = first destruct via destructor, then deallocate memory

How the memory is allocated and deallocated depends. If you use new and delete, the memory management is done by void* operator new(size_t) and void operator delete(void*).

fredoverflow
  • 256,549
  • 94
  • 388
  • 662
0

A C++ destructor is useful for freeing any resources owned by the object, not only memory. It may be files, sockets, mutexes, semaphores, or any other resource handles. Using a destructor is a smart way of preventing resource leaks. Wrap the resource handling in a C++ class and make a destructor that frees any allocated resources. I don't see any such method in Java. You have to explicitly free the resource, and this can be tricky if there are many possible exit paths.

A Fog
  • 4,360
  • 1
  • 30
  • 32
0

No, java does not support destructors. All freeing the memory task is done by GARBAGE COLLECTOR.

Java has it's own memory management feature using garbage collector. When you use finalize() the object becomes available for garbage collection and you don't need to explicitly call for the destructor. C# and Java don't want you to worry about destructor as they have feature of garbage collection.

Java is a bytecode language, it has very strong garbage detection. If you were to allow people to define their own destructors it is likely that they might make some mistakes. By automating the process, Java intends to prevent those mistakes.

Kowsigan Atsayam
  • 446
  • 1
  • 9
  • 20
-2

You do have the ability to control object destruction in Java. It simply uses a different idiom:

Connection conn = null;
try {
  conn = ...
  // do stuff
} finally {
  try { conn.close(); } catch (Exception e) { }
}

You could point out at this point that this isn't object destruction and that you could, for example, pass that object to something else and still have a reference to it. You are right on both counts. It is simply as close as Java (and most managed platforms) get.

But no Java does not, as you say, have a destructor mechanism as in C++. Some people mistake finalizers for this. They are not destructors and it is dangerous to use them as such.

Memory management for a programmer is hard. You can easily leak memory, particularly when doing multithreaded programming (also hard). Experience has shown that the cost of GC, while real and sometimes substantial, is well and truly justified in productivity increases and bug incidences in the vast majority of cases, which is why the vast majority of platforms now are "managed" (meaning they use garbage collection).

cletus
  • 616,129
  • 168
  • 910
  • 942
  • 9
    That doesn't destroy the *object* - it releases some resources associated with the object (the underlying OS handle, presumably) but not the object itself. – Jon Skeet Apr 09 '10 at 10:15