Thread overview | ||||||
---|---|---|---|---|---|---|
|
May 31, 2010 lifetime of dynamically allocated memory | ||||
---|---|---|---|---|
| ||||
I'm trying to figure out if a dynamically allocated memory in D is getting collected with this simple test (using tango): class Foo { ~this() { // destructor } } struct Item { Foo a; } Item[] items; items.length = 1; items[0] = Item(); items[0].a = new Foo(); items = null; GC.collect(); I assume that calling GC.collect(); forces gc to go through and free up memory for any unreferenced objects. It seems that the destructor for Foo isn't being called. I'm not sure if the reference is still used somewhere or do I have to explicitly call 'delete items[0].a' to ensure that the memory is freed? |
May 31, 2010 Re: lifetime of dynamically allocated memory | ||||
---|---|---|---|---|
| ||||
Posted in reply to dave | On 31.05.2010 22:27, dave wrote:
> I'm trying to figure out if a dynamically allocated memory in D is getting
> collected with this simple test (using tango):
>
> class Foo {
> ~this() {
> // destructor
> }
> }
>
> struct Item {
> Foo a;
> }
>
> Item[] items;
> items.length = 1;
> items[0] = Item();
> items[0].a = new Foo();
>
> items = null;
>
> GC.collect();
>
> I assume that calling GC.collect(); forces gc to go through and free up memory
> for any unreferenced objects. It seems that the destructor for Foo isn't being
> called. I'm not sure if the reference is still used somewhere or do I have to
> explicitly call 'delete items[0].a' to ensure that the memory is freed?
I'm not sure why it doesn't work. But it's always better to post the code you're actually using, since now we can't be sure that you're not doing something else then what you think you're doing. If you know what I mean. :)
|
May 31, 2010 Re: lifetime of dynamically allocated memory | ||||
---|---|---|---|---|
| ||||
Posted in reply to torhu | == Quote from torhu (no@spam.invalid)'s article
> On 31.05.2010 22:27, dave wrote:
> > I'm trying to figure out if a dynamically allocated memory in D is getting collected with this simple test (using tango):
> >
> > class Foo {
> > ~this() {
> > // destructor
> > }
> > }
> >
> > struct Item {
> > Foo a;
> > }
> >
> > Item[] items;
> > items.length = 1;
> > items[0] = Item();
> > items[0].a = new Foo();
> >
> > items = null;
> >
> > GC.collect();
> >
> > I assume that calling GC.collect(); forces gc to go through and free up memory for any unreferenced objects. It seems that the destructor for Foo isn't being called. I'm not sure if the reference is still used somewhere or do I have to explicitly call 'delete items[0].a' to ensure that the memory is freed?
> I'm not sure why it doesn't work. But it's always better to post the code you're actually using, since now we can't be sure that you're not doing something else then what you think you're doing. If you know what I mean. :)
I was trying it out on a clean slate...then I realized it works as intended, see attach file.
Then I was trying to figure out why it didn't work when I was testing it before and realized that I defined both the class and the struct within the scope of the function (attachment 2). Seems kinda weird that it wouldn't work that way...
|
June 01, 2010 Re: lifetime of dynamically allocated memory | ||||
---|---|---|---|---|
| ||||
Posted in reply to dave | On Mon, 31 May 2010 16:27:20 -0400, dave <garapata@gmail.com> wrote:
> I'm trying to figure out if a dynamically allocated memory in D is getting
> collected with this simple test (using tango):
>
> class Foo {
> ~this() {
> // destructor
> }
> }
>
> struct Item {
> Foo a;
> }
>
> Item[] items;
> items.length = 1;
> items[0] = Item();
> items[0].a = new Foo();
>
> items = null;
>
> GC.collect();
>
> I assume that calling GC.collect(); forces gc to go through and free up memory
> for any unreferenced objects. It seems that the destructor for Foo isn't being
> called. I'm not sure if the reference is still used somewhere or do I have to
> explicitly call 'delete items[0].a' to ensure that the memory is freed?
It looks like you found that this code sample works, but I'd warn against trying to "prove" the GC in this way. The scanner scans the stack and registers from each thread. The registers make it very difficult to prove things, because you don't know what's in the registers by looking at the code. So even if you have no references to objects when you call GC.collect, there may be stale registers that point to those objects.
And in response to your query, explicitly calling delete will ensure deleting of memory, but in general, you should let the GC do its job.
And for some more advice -- don't define destructors unless you have resources that are not managed by the GC (such as an open file). The GC does not guarantee order of destruction, so any GC-managed references in the object being destructed are undefined.
-Steve
|
Copyright © 1999-2021 by the D Language Foundation