www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Explicit memory deallocation

reply Julian Schick <julianschick gmx.net> writes:
I'm currently working with D 1.0 and experiencing really strange
access violations.

I have deactivated the GC using "std.gc.disable()" and free the memory
by myself. For a few days now, there have been occured those access violations.

The strange things about it:
- the access violations occur at completely different lines in the code
- the access violations occur often when a constructor is called
(I was tracing, and the debug message before the constructor call appeared, and
the one i placed as first command IN the constructor never
appeared, so there's evidently a problem with allocating memory)
- when I debug the application, i find names like this in the assembly next to
the point where the application stopped: _D3gcx2GC6gcLockC9ClassInfo
_D3gcx2GC12setFinalizerMFPvPFPvPvZvZv+00000094
-> Is the garbage collector still active??? (gcLock ???)
- If I remove a "delete" statement which I would say is absolutely "safe"
because it deletes an object from which I know that there is only one
reference to. And this reference will run out of scope just behind the "delete"
statement. Well, if I remove this statement, there are no more
access violations. That is only an example, I have a lot of other "delete"
statements in my code and I don't know what happens if I remove
 them as well.

I suppose, regarding these facts, that the GC is still running.
Am I not correctly disabling the GC?
If it is running, can't I free memory explicitely without disturbing the gc?
Are there any issues known which could be the reason for my problem?

Greetings
Julian Schick
Mar 10 2008
next sibling parent reply "Neil Vice" <psgdg swiftdsl.com.au> writes:
"Julian Schick" <julianschick gmx.net> wrote:
 I suppose, regarding these facts, that the GC is still running.
 Am I not correctly disabling the GC?
 If it is running, can't I free memory explicitely without disturbing the 
 gc?
 Are there any issues known which could be the reason for my problem?

 Greetings
 Julian Schick
"disable() temporarily disables garbage collection cycle, enable() then reenables them." Given this I suspect that the GC still expects to be in control of memory so even though the GC thread may not be running dynamically freeing things, constructor calls will still register pointers with the GC and expect some sort of internal consistency you are breaking with explicit destroys perhaps... Having said that, are the variables you're destroying "scope" at all (including "in" parameters)? If so then my understanding was that independantly of the GC thread these would be freed automatically when they go out of scope, resulting in them being destroyed twice if destroyed explicitly perhaps. Evidently I'm no expert but hopefully I've given you some ideas =)
Mar 10 2008
next sibling parent reply Julian Schick <julianschick gmx.net> writes:
 "disable() temporarily disables garbage collection cycle, enable() then 
 reenables them."
 
 Given this I suspect that the GC still expects to be in control of memory so 
 even though the GC thread may not be running dynamically freeing things, 
 constructor calls will still register pointers with the GC and expect some 
 sort of internal consistency you are breaking with explicit destroys 
 perhaps...
 
 Having said that, are the variables you're destroying "scope" at all 
 (including "in" parameters)? If so then my understanding was that 
 independantly of the GC thread these would be freed automatically when they 
 go out of scope, resulting in them being destroyed twice if destroyed 
 explicitly perhaps.
 
 Evidently I'm no expert but hopefully I've given you some ideas =) 
OK, I see, well, that's what I supposed, too. Then the question is how I can switch off the GC entirely. That should solve all my problems :-) Maybe there's also somebody out there, who can confirm that it is not possible to use GC and explicit freeing the same time. Because I tend to not believing that.
Mar 10 2008
parent reply Matthias Walter <walter mail.math.uni-magdeburg.de> writes:
Julian Schick Wrote:

 "disable() temporarily disables garbage collection cycle, enable() then 
 reenables them."
 
 Given this I suspect that the GC still expects to be in control of memory so 
 even though the GC thread may not be running dynamically freeing things, 
 constructor calls will still register pointers with the GC and expect some 
 sort of internal consistency you are breaking with explicit destroys 
 perhaps...
 
 Having said that, are the variables you're destroying "scope" at all 
 (including "in" parameters)? If so then my understanding was that 
 independantly of the GC thread these would be freed automatically when they 
 go out of scope, resulting in them being destroyed twice if destroyed 
 explicitly perhaps.
 
 Evidently I'm no expert but hopefully I've given you some ideas =) 
OK, I see, well, that's what I supposed, too. Then the question is how I can switch off the GC entirely. That should solve all my problems :-) Maybe there's also somebody out there, who can confirm that it is not possible to use GC and explicit freeing the same time. Because I tend to not believing that.
I had a bug in one of my apps which looked the same. For further debugging try to set the reference to null, after you explicitly delete it. The problem in my app was, that it pointed to already freed memory and the GC seemed to run, although deactivated, and finally trying to free this chunk. best regards Matthias Walter
Mar 12 2008
parent "Vladimir Panteleev" <thecybershadow gmail.com> writes:
On Wed, 12 Mar 2008 09:23:55 +0200, Matthias Walter <walter mail.math.un=
i-magdeburg.de> wrote:

 Julian Schick Wrote:

 "disable() temporarily disables garbage collection cycle, enable() =
then
 reenables them."

 Given this I suspect that the GC still expects to be in control of =
memory so
 even though the GC thread may not be running dynamically freeing th=
ings,
 constructor calls will still register pointers with the GC and expe=
ct some
 sort of internal consistency you are breaking with explicit destroy=
s
 perhaps...

 Having said that, are the variables you're destroying "scope" at al=
l
 (including "in" parameters)? If so then my understanding was that
 independantly of the GC thread these would be freed automatically w=
hen they
 go out of scope, resulting in them being destroyed twice if destroy=
ed
 explicitly perhaps.

 Evidently I'm no expert but hopefully I've given you some ideas =3D=
)
 OK, I see, well, that's what I supposed, too.
 Then the question is how I can switch off the GC entirely.
 That should solve all my problems :-)

 Maybe there's also somebody out there, who can confirm
 that it is not possible to use GC and explicit freeing the same time.=
 Because I tend to not believing that.
I had a bug in one of my apps which looked the same. For further debug=
ging try to set the reference to null, after you explicitly delete it. T= he problem in my app was, that it pointed to already freed memory and th= e GC seemed to run, although deactivated, and finally trying to free thi= s chunk. This doesn't make much sense... can you reproduce the issue? -- = Best regards, Vladimir mailto:thecybershadow gmail.com
Mar 12 2008
prev sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Neil Vice" <psgdg swiftdsl.com.au> wrote in message 
news:fr3k2v$30ss$1 digitalmars.com...

 "disable() temporarily disables garbage collection cycle, enable() then 
 reenables them."

 Given this I suspect that the GC still expects to be in control of memory 
 so even though the GC thread may not be running dynamically freeing 
 things, constructor calls will still register pointers with the GC and 
 expect some sort of internal consistency you are breaking with explicit 
 destroys perhaps...
The current GC implementation that D uses (no matter what library you're using) is synchronous, that is, it does not run in a separate thread. GC collections will only happen on memory allocations. When the GC is disabled, it should not perform any collections.
Mar 10 2008
parent Frank Benoit <keinfarbton googlemail.com> writes:
Jarrett Billingsley schrieb:
 "Neil Vice" <psgdg swiftdsl.com.au> wrote in message 
 news:fr3k2v$30ss$1 digitalmars.com...
 
 "disable() temporarily disables garbage collection cycle, enable() then 
 reenables them."

 Given this I suspect that the GC still expects to be in control of memory 
 so even though the GC thread may not be running dynamically freeing 
 things, constructor calls will still register pointers with the GC and 
 expect some sort of internal consistency you are breaking with explicit 
 destroys perhaps...
The current GC implementation that D uses (no matter what library you're using) is synchronous, that is, it does not run in a separate thread. GC collections will only happen on memory allocations. When the GC is disabled, it should not perform any collections.
(tango user) the GC disable disables collection runs as already said. That means, if there is no more memory, new memory is requested from the OS. In the normal case, the GC would first do the collection to try to get the needed memory. Everything else should work like befor. Explicit calls to "delete" should work as usual.
Mar 10 2008
prev sibling parent reply "Unknown W. Brackets" <unknown simplemachines.org> writes:
It's important to remember that calling a function can't remove compiled 
code.  The compiler is by no means detecting that you are calling 
std.gc.disable(), so it must compile in calls to the gc even if they are 
being ignored.

The easiest way to check on the gc is probably to trace destructor 
calls.  IIRC (I may be wrong), it calls those synchronously with freeing 
the memory, so if you have one called twice on the same reference you 
know the problem.

I know you mentioned it happens when a constructor is called, but it 
could simply be that the gc freeing something twice is horribly 
destroying something inside the gc that is still happening...

Lastly, if none of that helps, checking if you're using auto for 
automatic freeing.  This isn't the gc, technically I think, so I'm 
pretty sure it will still automatically free when it falls off the stack 
even if the gc is disabled.

Sorry, I'm about to go to bed and we've got DST here in the states, so I 
feel I haven't organized my post as best I should have...

-[Unknown]


Julian Schick wrote:
 I'm currently working with D 1.0 and experiencing really strange
 access violations.
 
 I have deactivated the GC using "std.gc.disable()" and free the memory
 by myself. For a few days now, there have been occured those access violations.
 
 The strange things about it:
 - the access violations occur at completely different lines in the code
 - the access violations occur often when a constructor is called
 (I was tracing, and the debug message before the constructor call appeared,
and the one i placed as first command IN the constructor never
 appeared, so there's evidently a problem with allocating memory)
 - when I debug the application, i find names like this in the assembly next to
the point where the application stopped: _D3gcx2GC6gcLockC9ClassInfo
 _D3gcx2GC12setFinalizerMFPvPFPvPvZvZv+00000094
 -> Is the garbage collector still active??? (gcLock ???)
 - If I remove a "delete" statement which I would say is absolutely "safe"
 because it deletes an object from which I know that there is only one
 reference to. And this reference will run out of scope just behind the
"delete" statement. Well, if I remove this statement, there are no more
 access violations. That is only an example, I have a lot of other "delete"
 statements in my code and I don't know what happens if I remove
  them as well.
 
 I suppose, regarding these facts, that the GC is still running.
 Am I not correctly disabling the GC?
 If it is running, can't I free memory explicitely without disturbing the gc?
 Are there any issues known which could be the reason for my problem?
 
 Greetings
 Julian Schick
Mar 11 2008
parent reply downs <default_357-line yahoo.de> writes:
Unknown W. Brackets wrote:
 Lastly, if none of that helps, checking if you're using auto for
 automatic freeing.
Being a bit nitpicky, but auto is for pure type inference. Scope is for automatic freeing :) It was changed a while back. --downs
Mar 11 2008
parent reply Sean Kelly <sean invisibleduck.org> writes:
== Quote from downs (default_357-line yahoo.de)'s article
 Unknown W. Brackets wrote:
 Lastly, if none of that helps, checking if you're using auto for
 automatic freeing.
Being a bit nitpicky, but auto is for pure type inference. Scope is for automatic freeing :) It was changed a while back.
Unfortunately, both still work. Sean
Mar 11 2008
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Sean Kelly wrote:
 == Quote from downs (default_357-line yahoo.de)'s article
 Unknown W. Brackets wrote:
 Lastly, if none of that helps, checking if you're using auto for
 automatic freeing.
Being a bit nitpicky, but auto is for pure type inference. Scope is for automatic freeing :) It was changed a while back.
Unfortunately, both still work.
I think that's only true for the case where it is part of the class definition. As in: scope class Foo {...} For that, yes, auto class Foo{...} still works and means the same thing. But that's the only case in which scope and auto are still interchangeable, right? Still I would have thought 'auto class' would have been removed at least in the D2 branch. But I just tried it out and it's still there. --bb
Mar 11 2008
parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Bill Baxter" <dnewsgroup billbaxter.com> wrote in message 
news:fr6mbu$1pvd$1 digitalmars.com...

 I think that's only true for the case where it is part of the class 
 definition.   As in:

    scope class Foo {...}
Actually the class doesn't even have to be "scope" and the distinction is a bit weirder. auto f = new Foo(); will not make it scoped, and just performs type inference. auto Foo f = new Foo(); _is_ scoped. Why? I don't know. Left in there? Intentional? fuh.
Mar 11 2008