Thread overview | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
August 18, 2014 Why does D rely on a GC? | ||||
---|---|---|---|---|
| ||||
First of all I don't want to insult anyone on language design, I just want to know the reason behind the "always on" GC. I know that the GC as several advantages over reference counting, especially when it comes to immutable data structures. What I don't (correct me if i am wrong) understand is why every heap allocation has to be garbage collected, like classes, dynamic arrays etc. Does a GC still have advantages over heap allocations that do not need to be reference counted such as the unique_ptr in c++? The dlang homepage stats: Destructors are used to deallocate resources acquired by an object. For most classes, this resource is allocated memory. With garbage collection, most destructors then become empty and can be discarded entirely. If I understand it correctly it means that D has a GC, so most classes don't need a destructor anymore because they don't need to do any cleanup. I am not totally convinced that this would be a good trade off in general. Maybe someone could shine some light on this statement? |
August 18, 2014 Re: Why does D rely on a GC? | ||||
---|---|---|---|---|
| ||||
Posted in reply to maik klein | On Mon, 18 Aug 2014 10:01:57 +0000
maik klein via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> First of all I don't want to insult anyone on language design, I
> just want to know the reason behind the "always on" GC.
> I know that the GC as several advantages over reference counting,
> especially when it comes to immutable data structures.
> What I don't (correct me if i am wrong) understand is why every
> heap allocation has to be garbage collected, like classes,
> dynamic arrays etc.
> Does a GC still have advantages over heap allocations that do not
> need to be reference counted such as the unique_ptr in c++?
> The dlang homepage stats:
>
> Destructors are used to deallocate resources acquired by an object. For most classes, this resource is allocated memory. With garbage collection, most destructors then become empty and can be discarded entirely.
>
> If I understand it correctly it means that D has a GC, so most classes don't need a destructor anymore because they don't need to do any cleanup. I am not totally convinced that this would be a good trade off in general. Maybe someone could shine some light on this statement?
The biggest reason is memory safety. With a GC, it's possible to make compiler guarantees about memory safety, whereas with manual memory management, it isn't. It's also pretty hard to do stuff like automatic closures and delegates without a GC, and the behavior of D's dynamic arrays - particularly with regards to slices - is much harder to do without a GC. The result is that there are a number of features which you lose out on if you don't have D's GC (though they're not features a language like C++ has, since it doesn't have a GC).
However, it's also not true that the GC is necessarily always on. You can
disable it. It's just that you do so, you lose out on certain language
features, and memory management becomes a bit harder (particularly when it
comes to constructing classes in malloced memory, but the custom allocators
which are in the works should fix that). However, with the way a typical D
program works, a lot more goes on the stack than happens with a typical
GC language, so the fact that it has a GC wouldn't be as big an impediment as
it is with some other languages, if you couldn't turn it off.
So, having the GC gives us a number of features that aren't really possible without it, and unlike languages like Java, you _can_ turn it off if you want to, though you do lose out on some features when you do. So, ultimately, about all we really lose out on by having the GC is having folks who want a systems language freaking out about the fact that D has a GC and frequently assume that that means that they have to it and that D is not performant.
- Jonathan M Davis
|
August 18, 2014 Re: Why does D rely on a GC? | ||||
---|---|---|---|---|
| ||||
Posted in reply to maik klein | On Monday, 18 August 2014 at 10:01:59 UTC, maik klein wrote:
> First of all I don't want to insult anyone on language design, I just want to know the reason behind the "always on" GC.
> I know that the GC as several advantages over reference counting, especially when it comes to immutable data structures.
> What I don't (correct me if i am wrong) understand is why every heap allocation has to be garbage collected, like classes, dynamic arrays etc.
> Does a GC still have advantages over heap allocations that do not need to be reference counted such as the unique_ptr in c++?
> The dlang homepage stats:
>
> Destructors are used to deallocate resources acquired by an object. For most classes, this resource is allocated memory. With garbage collection, most destructors then become empty and can be discarded entirely.
>
> If I understand it correctly it means that D has a GC, so most classes don't need a destructor anymore because they don't need to do any cleanup. I am not totally convinced that this would be a good trade off in general. Maybe someone could shine some light on this statement?
A good reason is the ability to write lock-free algorithms, which are very hard to implement without GC support. This is the main reason why C++11 has a GC API and Herb Sutter will be discussing about GC in C++ at CppCon.
Reference counting is only a win over GC with compiler support for reducing increment/decrement operations via dataflow analysis.
C++ programs with heavy use of unique_ptr/shared_ptr/weak_ptr are slower than other languages with GC support, because those classes are plain library types without compiler support. Of course, compiler vendors can have blessed library types, but the standard does not require it.
RC also has performance impact when deleting big data structures. You can optimize this away big using asynchronous deletion, but eventually you are just doing GC with another name.
As for feasibility of a GC in a systems programming language, just think the Mesa/Cedar environment at Xerox PARC was a system programming language using reference counting with a GC for collecting cycles.
--
Paulo
|
August 18, 2014 Re: Why does D rely on a GC? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | Jonathan M Davis:
> The biggest reason is memory safety. With a GC, it's possible to make compiler guarantees about memory safety, whereas with
> manual memory management, it isn't.
Unless you have a very smart type system and you accept some compromises (Rust also uses a reference counter some some cases, but I think most allocations don't need it).
Bye,
bearophile
|
August 18, 2014 Re: Why does D rely on a GC? | ||||
---|---|---|---|---|
| ||||
Posted in reply to maik klein | On Monday, 18 August 2014 at 10:01:59 UTC, maik klein wrote:
> Does a GC still have advantages over heap allocations that do not need to be reference counted such as the unique_ptr in c++?
Isn't unique_ptr unique? What to do when the object is non-unique?
|
August 18, 2014 Re: Why does D rely on a GC? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kagamin | On Monday, 18 August 2014 at 12:06:27 UTC, Kagamin wrote: > On Monday, 18 August 2014 at 10:01:59 UTC, maik klein wrote: >> Does a GC still have advantages over heap allocations that do not need to be reference counted such as the unique_ptr in c++? > > Isn't unique_ptr unique? What to do when the object is non-unique? Not sure what you mean by unqiue. It's like a reference counted object but with a counter of 1, meaning if it goes out of scope it will be deleted. (But it does not do any reference counting). I think D also has a unique ptr. https://github.com/D-Programming-Language/phobos/blob/master/std/typecons.d#L58 Is it correct that when I create a class it will always be on the heap and therefore be garbage collected? class Foo .. So I don't have the option to put a class on the stack like in C++? auto foo = Foo(); //stack auto foo_ptr = new Foo(); // heap If I do something like: auto ptr = Unique(Foo); Would the GC still be used, or would the resource be freed by the destructor? |
August 18, 2014 Re: Why does D rely on a GC? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Maik Klein | On Monday, 18 August 2014 at 12:27:44 UTC, Maik Klein wrote: > Is it correct that when I create a class it will always be on the heap and therefore be garbage collected? > > class Foo > .. > > So I don't have the option to put a class on the stack like in C++? > > auto foo = Foo(); //stack > auto foo_ptr = new Foo(); // heap > > If I do something like: > > auto ptr = Unique(Foo); > > Would the GC still be used, or would the resource be freed by the destructor? http://dlang.org/phobos/std_typecons.html#.scoped |
August 18, 2014 Re: Why does D rely on a GC? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kagamin | On Monday, 18 August 2014 at 12:06:27 UTC, Kagamin wrote:
> On Monday, 18 August 2014 at 10:01:59 UTC, maik klein wrote:
>> Does a GC still have advantages over heap allocations that do not need to be reference counted such as the unique_ptr in c++?
>
> Isn't unique_ptr unique? What to do when the object is non-unique?
Yes, unique_ptr is unique :-) It is not reference counted -- it just destroys the owned object when it goes out of scope. The near thing about unique_ptrs is that you can move them around, transferring ownership.
If the object is non-unique, then typically C++ programmers will use shared_ptr (+ weak_ptr).
I'm not sure what the status of std.typecons.Unique is. Last I heard it had some issues, but I haven't tried it much myself.
|
August 18, 2014 Re: Why does D rely on a GC? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Peter Alexander | On Monday, 18 August 2014 at 12:55:52 UTC, Peter Alexander wrote:
> On Monday, 18 August 2014 at 12:06:27 UTC, Kagamin wrote:
>> On Monday, 18 August 2014 at 10:01:59 UTC, maik klein wrote:
>>> Does a GC still have advantages over heap allocations that do not need to be reference counted such as the unique_ptr in c++?
>>
>> Isn't unique_ptr unique? What to do when the object is non-unique?
>
> Yes, unique_ptr is unique :-) It is not reference counted -- it just destroys the owned object when it goes out of scope. The near thing about unique_ptrs is that you can move them around, transferring ownership.
>
> If the object is non-unique, then typically C++ programmers will use shared_ptr (+ weak_ptr).
>
> I'm not sure what the status of std.typecons.Unique is. Last I heard it had some issues, but I haven't tried it much myself.
So if it's not known to be unique beforehand, the safe bet is to use shared_ptr, if the ownership is not known beforehand, the safe bet is to not use weak_ptr, then you are left with all references annotated with spurious shared_ptr all over the place. It will be also easy to mess up the annotations and get dangling pointer.
|
August 18, 2014 Re: Why does D rely on a GC? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Maik Klein | On 18/08/2014 13:27, Maik Klein wrote:
> If I do something like:
>
> auto ptr = Unique(Foo);
>
> Would the GC still be used, or would the resource be freed by the
> destructor?
It uses GC allocation, but the memory will be freed deterministically:
{
Unique!Foo u = new Foo;
// u's destructor will call 'delete' on its instance of Foo here
}
|
Copyright © 1999-2021 by the D Language Foundation