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?

11
  • 6
    Your question has also the answer. Instead of destructor, the java perform the garbage collections Commented Apr 9, 2010 at 10:13
  • 24
    -1 for unsubstantiated claims on garbage collection. Commented Apr 9, 2010 at 10:42
  • 3
    @Abhishek: if that's your only goal, then you should avoid giving such controversive, unsubstantiated claims. Commented Apr 9, 2010 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. Commented Apr 9, 2010 at 11:13
  • 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. ;) Commented Apr 10, 2010 at 7:07

10 Answers 10

56

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.

Sign up to request clarification or add additional context in comments.

7 Comments

I think developers are lazy (in a good way) by nature!
free isn't free either.
@TomHawtin-tackline As one guy said, if something is free it means that you are the product :)
@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.
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.
|
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.

3 Comments

@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.
Actually, I'm not just disputing the assertion. I'm also providing a reference to hard evidence that (IMO) disproves it.
To the random anonymous downvoter: please feel free to explain why you think this is a bad answer.
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.

4 Comments

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.
@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).
@andyjohnson: Storage is immendiately unavailable. The actual deallocation may happen later - batch processing is not unheard of.
@andy Sure there is a Garbage Collector for C++, it's just not standard: hpl.hp.com/personal/Hans_Boehm/gc
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?

9 Comments

"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 on the contrary. Java offers the finally {} block.
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 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.
@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 <function-name>" to be logged/traced. When that object goes out of scope, the destructor causes "Exited <function-name>" 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.
|
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.

2 Comments

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 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.
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.

3 Comments

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.
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.
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.
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*).

Comments

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.

Comments

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.

Comments

-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).

1 Comment

That doesn't destroy the object - it releases some resources associated with the object (the underlying OS handle, presumably) but not the object itself.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.