Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
March 25, 2006 Garbage collection from associative arrays | ||||
---|---|---|---|---|
| ||||
The following program creates a couple of instances of a class and stores them in an associative array. It then tries to periodically access those instances via the associative array, performing garbage collects in between. As it appears, a fullCollect will destroy the objects, even though they are stored in an associative array. This leads to an access violation in the second loop. Is this a known bug? Can it be fixed? Are there any workarounds? Regards, Sebastian Output on my machine: Loading... class created class created class created 97 98 99 class killed (99) class killed (98) class killed (97) Error: Access Violation Program code: private { import std.gc; import std.stdio; } class SomeClass { this(char value) { writefln("class created"); _value = value; } ~this() { writefln("class killed (%d)", _value); } char value() { return _value; } private { char _value; } } static char[] allChars = [ 'a', 'b', 'c' ]; SomeClass[char] _chars; void _realLoad() { writefln("Loading..."); foreach(char ch; allChars) { _chars[ch] = new SomeClass(ch); } } int main(char[][] args) { bool done = false; _realLoad(); while(!done) { foreach(char ch; allChars) { SomeClass obj = _chars[ch]; writefln("%d", obj.value); } std.gc.fullCollect(); } } |
March 25, 2006 Re: Garbage collection from associative arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sebastian Beschke | Well, I found a workaround: Just modify the index type of the associative array to int.
Sebastian Beschke schrieb:
> The following program creates a couple of instances of a class and stores them in an associative array. It then tries to periodically access those instances via the associative array, performing garbage collects in between.
>
> As it appears, a fullCollect will destroy the objects, even though they are stored in an associative array. This leads to an access violation in the second loop.
>
> Is this a known bug? Can it be fixed? Are there any workarounds?
>
> Regards, Sebastian
>
>
>
> Output on my machine:
>
> Loading...
> class created
> class created
> class created
> 97
> 98
> 99
> class killed (99)
> class killed (98)
> class killed (97)
> Error: Access Violation
>
>
> Program code:
>
> private {
> import std.gc;
> import std.stdio;
> }
>
>
> class SomeClass {
> this(char value) {
> writefln("class created");
> _value = value;
> }
>
> ~this()
> {
> writefln("class killed (%d)", _value);
> }
>
> char value() {
> return _value;
> }
>
>
> private {
> char _value;
> }
> }
>
> static char[] allChars = [
> 'a', 'b', 'c'
> ];
>
>
> SomeClass[char] _chars;
>
> void _realLoad() {
> writefln("Loading...");
> foreach(char ch; allChars) {
> _chars[ch] = new SomeClass(ch);
> }
> }
>
>
>
> int main(char[][] args)
> {
> bool done = false;
> _realLoad();
>
> while(!done)
> {
> foreach(char ch; allChars) {
> SomeClass obj = _chars[ch];
> writefln("%d", obj.value);
> }
> std.gc.fullCollect();
> }
> }
|
March 25, 2006 Re: Garbage collection from associative arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sebastian Beschke | Sebastian Beschke wrote:
> Sebastian Beschke schrieb:
>> The following program creates a couple of instances of a class and stores them in an associative array. It then tries to periodically access those instances via the associative array, performing garbage collects in between.
>>
>> As it appears, a fullCollect will destroy the objects, even though they are stored in an associative array. This leads to an access violation in the second loop.
>>
>> Is this a known bug? Can it be fixed? Are there any workarounds?
>
> Well, I found a workaround: Just modify the index type of the associative array to int.
Yeah. The error lies in the AA implementation. The pointers are not stored on the correct alignment. Each node of the AA is allocated in the following way:
e = cast(aaA *) cast(void*) new byte[aaA.sizeof + keysize + valuesize];
The aaA struct contains two pointers (left&right) and a uint hash. That is 12 bytes on a 32 bit machine. If keysize isn't divisible by 4, the pointers stored as values will not be 4-byte aligned.
/Oskar
|
March 25, 2006 Re: Garbage collection from associative arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sebastian Beschke | Sebastian Beschke wrote: > The following program creates a couple of instances of a class and > stores them in an associative array. It then tries to periodically > access those instances via the associative array, performing garbage > collects in between. > > As it appears, a fullCollect will destroy the objects, even though they > are stored in an associative array. This leads to an access violation in > the second loop. > > Is this a known bug? Can it be fixed? Are there any workarounds? I ran into something similar to this when first writing Ares, as I was using a map to store thread handles. Basically, when a value is being added to the AA, the AA is first modified to hold some uninitialized data, then memory is allocated, then everything is initialized. As it's possible this is the same problem, you may want to check out my fix here: http://svn.dsource.org/projects/ares/trunk/src/dmdrt/aaA.d Look for "better to fully construct" as a portion of the comment documenting the change. Sean |
March 26, 2006 Re: Garbage collection from associative arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sebastian Beschke Attachments: | Sebastian Beschke schrieb am 2006-03-25: > The following program creates a couple of instances of a class and stores them in an associative array. It then tries to periodically access those instances via the associative array, performing garbage collects in between. > > As it appears, a fullCollect will destroy the objects, even though they are stored in an associative array. This leads to an access violation in the second loop. > > Is this a known bug? Can it be fixed? Are there any workarounds? > > Regards, Sebastian > > > > Output on my machine: > > Loading... > class created > class created > class created > 97 > 98 > 99 > class killed (99) > class killed (98) > class killed (97) > Error: Access Violation > > > Program code: > > private { > import std.gc; > import std.stdio; > } > > > class SomeClass { > this(char value) { > writefln("class created"); > _value = value; > } > > ~this() > { > writefln("class killed (%d)", _value); > } > > char value() { > return _value; > } > > > private { > char _value; > } > } > > static char[] allChars = [ > 'a', 'b', 'c' > ]; > > > SomeClass[char] _chars; > > void _realLoad() { > writefln("Loading..."); > foreach(char ch; allChars) { > _chars[ch] = new SomeClass(ch); > } > } > > > > int main(char[][] args) > { > bool done = false; > _realLoad(); > > while(!done) > { > foreach(char ch; allChars) { > SomeClass obj = _chars[ch]; > writefln("%d", obj.value); > } > std.gc.fullCollect(); > } > } Added to DStress as http://dstress.kuehne.cn/run/a/associative_array_19_A.d http://dstress.kuehne.cn/run/a/associative_array_19_B.d http://dstress.kuehne.cn/run/a/associative_array_19_C.d http://dstress.kuehne.cn/run/a/associative_array_19_D.d http://dstress.kuehne.cn/run/a/associative_array_19_E.d http://dstress.kuehne.cn/run/a/associative_array_19_F.d http://dstress.kuehne.cn/run/a/associative_array_19_G.d http://dstress.kuehne.cn/run/a/associative_array_19_H.d http://dstress.kuehne.cn/run/a/associative_array_19_I.d http://dstress.kuehne.cn/run/a/associative_array_19_J.d http://dstress.kuehne.cn/run/a/associative_array_19_K.d http://dstress.kuehne.cn/run/a/associative_array_19_L.d http://dstress.kuehne.cn/run/a/associative_array_19_M.d http://dstress.kuehne.cn/run/a/associative_array_19_N.d http://dstress.kuehne.cn/run/a/associative_array_19_O.d http://dstress.kuehne.cn/run/a/associative_array_19_P.d http://dstress.kuehne.cn/run/a/associative_array_19_Q.d http://dstress.kuehne.cn/run/a/associative_array_19_R.d http://dstress.kuehne.cn/run/a/associative_array_19_S.d http://dstress.kuehne.cn/run/a/associative_array_19_T.d http://dstress.kuehne.cn/run/a/associative_array_19_U.d http://dstress.kuehne.cn/run/a/associative_array_19_V.d http://dstress.kuehne.cn/run/a/associative_array_19_W.d http://dstress.kuehne.cn/run/a/associative_array_19_X.d http://dstress.kuehne.cn/run/a/associative_array_19_Y.d http://dstress.kuehne.cn/run/a/associative_array_19_Z.d Thomas |
Copyright © 1999-2021 by the D Language Foundation