views:

134

answers:

7

You can create new objects, but when you've finished using them there's no real way to destroy them immediately as well?

Why didn't every OOP runtime implement such behaviour?

I'm sure we as developers could (often) organize for object instances to be destroyed when we've finished using them.

function work(){
    var p1:Point = new Point(x, y);
    var p2:Point = new Point(x2, y2);

    ....

    destroy p1;
    destroy p2;
}
+9  A: 

Speaking from .NET, the answer is memory safety.

Consider two items A and B (objects or methods) both holding a reference to Object X.
And now A does a destroy X;. B is then left with an invalid reference. This is a common error pattern in unmanaged languages. Removing manual destruction prevents this.

But an equally important issue is: Would it help much? The answer is no. Short lived memory is very cheap in .NET. The destroy as you propose it would not be of any value.

Henk Holterman
Actually that's called memory safety and applies to all systems, not just .NET (the only way to avoid dangling pointers is not to release memory until it can be proven to be unreferenced now and in the future, which implies removing pointers/pointer arithmetic). But yeah.
delnan
As far as I understand it, Memory-safety is part of Type-safety, right?
Henk Holterman
Wiki says "Type safety is closely linked to memory safety [...]", and, about every typesafe language provides memory safety as well. I was just being pedantic :)
delnan
+5  A: 

In brief, because that in general complicates programming tasks. Manual memory management requires considerable skills and effort to get right - effort you can't use for the actual task you are to solve.

The scenario you show above is common, but far from being the only one. What if you return a reference to one of the objects? What if you pass a reference to a called method (where it may get stored)? Etc etc. These are all issues you need to think of before you can responsibly destroy your objects. Altogether these are known as "ownership".

The other side of the coin is, would it really have a positive effect to be able to destroy objects at a specified point during execution? This makes possible destructors, and RAII in C++, which is a very powerful idiom. Java doesn't have it, and when I started to use Java, I often missed it. However, there are ways to solve these issues effectively in Java as well (such as the finally block). However elegant RAII is, it still does not pay for the whole mess that manual memory management can cause.

Then you might suggest, "why can't we have both: explicit destruction of objects when I want to, and garbage collection for the rest?". And you can start running for cover before the compiler writers and JVM implementors get you :-) That would complicate matters so much, noone would do it without a really huge, tangible benefit. And manual memory management offers no such thing.

Péter Török
+2  A: 

No, just no. One of the best things Java/C# gives you over C++ is memory management - if you have to take care of it yourself then it's more error prone and if people have the possibility they would use and abuse it creating more and more errors and memory leaks either by forgetting to deallocate something or by doing it too early. Designing/coding large projects is hard enough without thinking about memory management.

Zenzen
+1  A: 

C++ is an OOP language; and it provides 'new' keyword that can be used to construct an object and a 'delete' keyword that can be used to destroy an object. The delete object can have disastrous effect in C++ if not used with care; if a single object has two pointers referencing it, and you delete the object from one of the pointer, the other pointer becomes invalid and any attempt to use it will be undefined behavior (typically the program will try to use the value in the memory location; which may already be reallocated for other purpose by the runtime)

Lie Ryan
+1  A: 

For Java, see Runtime.gc().

For C# see System.GC.Collect

I'm not completely sure about C#, but in Java you can only request that Garbage Collection happen but the decision of whether or not to actually clean up unused references is left up to the Virtual Machine.

There is much debate as to whether C++ style memory management vs. garbage collection in interpreted languages performs better, but if you're doing Java or C# work I'd be suspicious as to whether you really need to force garbage collection and in general if you're coming from C++ I would recommend resisting the temptation to manage memory and let the VM optimizations do it for you. You should just make sure you have released all references to objects you are not using so that they can be garbage collected. I wouldn't worry about when.

Frank Flannigan
Requesting GC is completely different from directly destroying objects.
Henk Holterman
+2  A: 

The reason that not all OO languages have garbage collection(Java) or explicit memory deallocation (C++) is a consequence of the strategy chosen in the design of each language. Java does not allow programmers to explicitely allocate and deallocate memory. Instead programers handle reference variables when they do

Point p = new Point(x,y);//p is a reference variable

and the deallocation for p is done through garbage collection (automatically). In order to have garbage collection, you opt to explicit symbolic referencing and not use pointers. As a result C++ does not have garbage collection and it can not be provided as an inherent feature of the language. Programmers must explicitely deallocate memory using

delete p;

Or write their own implementations of garbage collection. So either you have garbage collection or manual deallocation depending on the design of the OO language. You can not have both.

+1  A: 

You can set the existing reference to null or similar in most langauges which will then allow the runtime to garbage collect it should it wish to.

I guess the price you pay for the convenience of letting the system mange your memory is that you lose much of the ability to do so yourself when you want to

John Burton