www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Prevent Garbage Collector

reply "Jeroen Bollen" <jbinero gmail.com> writes:
Is there a way to prevent the Garbage collector from running on 
one particular object? Something like:

int* CreatePermanentInt() {
     int i = 5;
     return &i;
}

And i wouldn't be collected after this.
Jan 04 2014
next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Saturday, 4 January 2014 at 17:15:12 UTC, Jeroen Bollen wrote:
 Is there a way to prevent the Garbage collector from running on 
 one particular object? Something like:
I would just malloc it. int* CreatePermanentInt() { int* i = malloc(int.sizeof); *i = 5; return i; } The malloced thing itself won't be freed, nor will its contents be scanned by the gc (unless you use GC.addRange yourself) so you can use it to hack some weak references too.
Jan 04 2014
next sibling parent reply "Jeroen Bollen" <jbinero gmail.com> writes:
On Saturday, 4 January 2014 at 17:16:53 UTC, Adam D. Ruppe wrote:
 On Saturday, 4 January 2014 at 17:15:12 UTC, Jeroen Bollen 
 wrote:
 Is there a way to prevent the Garbage collector from running 
 on one particular object? Something like:
I would just malloc it. int* CreatePermanentInt() { int* i = malloc(int.sizeof); *i = 5; return i; } The malloced thing itself won't be freed, nor will its contents be scanned by the gc (unless you use GC.addRange yourself) so you can use it to hack some weak references too.
Do I get malloc from the C library or does D also have a function for this?
Jan 04 2014
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Saturday, 4 January 2014 at 17:19:30 UTC, Jeroen Bollen wrote:
 Do I get malloc from the C library or does D also have a 
 function for this?
import core.stdc.stdlib; // malloc and free are in here it uses it from the C library but the standard c lib is easily accessible from D in the core.stdc package.
Jan 04 2014
next sibling parent "Jeroen Bollen" <jbinero gmail.com> writes:
On Saturday, 4 January 2014 at 17:22:44 UTC, Adam D. Ruppe wrote:
 On Saturday, 4 January 2014 at 17:19:30 UTC, Jeroen Bollen 
 wrote:
 Do I get malloc from the C library or does D also have a 
 function for this?
import core.stdc.stdlib; // malloc and free are in here it uses it from the C library but the standard c lib is easily accessible from D in the core.stdc package.
Yeah I knew about the C library, just wasn't sure if D also had it's own function.
Jan 04 2014
prev sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
And GC.addRange is in core.memory if you want that.

http://dlang.org/phobos/core_memory.html#addRange
Jan 04 2014
parent reply "Jeroen Bollen" <jbinero gmail.com> writes:
On Saturday, 4 January 2014 at 17:24:24 UTC, Adam D. Ruppe wrote:
 And GC.addRange is in core.memory if you want that.

 http://dlang.org/phobos/core_memory.html#addRange
Would that work with structs too? Struct* i = malloc(Struct.sizeof); i = &Struct(params);
Jan 04 2014
parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Saturday, 4 January 2014 at 17:37:00 UTC, Jeroen Bollen wrote:
 Would that work with structs too?

 Struct* i = malloc(Struct.sizeof);
 i = &Struct(params);
You don't want to take the address of a temporary, not with structs nor int. But you could copy it with *i = Struct(params) and that should be ok. There's also std.conv.emplace that might be useful. And bearophile is right too, of course, that it will need a cast on malloc. Struct* i = cast(Struct*) malloc(Struct.sizeof);
Jan 04 2014
prev sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Adam D. Ruppe:

 int* CreatePermanentInt() {
    int* i = malloc(int.sizeof);
    *i = 5;
    return i;
 }
In D malloc needs a cast void -> T*. In D a wrapper like this could help you avoid some mistakes making the code more DRY (untested): T* cMalloc(T)() nothrow { return cast(T*)malloc(T.sizeof); } T* cCalloc(T)(in size_t n) nothrow { return cast(T*)calloc(n, T.sizeof); } auto i = cMalloc!int; auto j = cCalloc!int; Bye, bearophile
Jan 04 2014
prev sibling next sibling parent "anonymous" <anonymous example.com> writes:
On Saturday, 4 January 2014 at 17:15:12 UTC, Jeroen Bollen wrote:
 Is there a way to prevent the Garbage collector from running on 
 one particular object? Something like:

 int* CreatePermanentInt() {
     int i = 5;
     return &i;
 }

 And i wouldn't be collected after this.
i isn't GC managed here. It's a stack variable. Returning references to the stack is a no-no, because the stack will be reused. If i was actually GC managed, it would not be collected, because there's a reference to it: ---- int* CreatePermanentInt() { int* i = new int; *i = 5; return i; } ----
Jan 04 2014
prev sibling parent reply "Jeroen Bollen" <jbinero gmail.com> writes:
Also a somewhat unrelated question, variables in D get 
initialized by default, do they also when you define them right 
after? Something like:

int[] iryy = new int[](50); // Will the array elements be 
initialized to 0?

foreach(int i; irry) {
     i = 20;
}
Jan 04 2014
next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Sunday, 5 January 2014 at 00:17:12 UTC, Jeroen Bollen wrote:
 Also a somewhat unrelated question, variables in D get 
 initialized by default, do they also when you define them right 
 after? Something like:
Maybe. Logically, it is always initialized unless you explicitly tell it not to ( = void on declarations, not sure about making new return uniniialized memory), but the optimizer might see that the initalization is useless and skip it.
Jan 04 2014
next sibling parent reply "Jeroen Bollen" <jbinero gmail.com> writes:
On Sunday, 5 January 2014 at 00:28:00 UTC, Adam D. Ruppe wrote:
 On Sunday, 5 January 2014 at 00:17:12 UTC, Jeroen Bollen wrote:
 Also a somewhat unrelated question, variables in D get 
 initialized by default, do they also when you define them 
 right after? Something like:
Maybe. Logically, it is always initialized unless you explicitly tell it not to ( = void on declarations, not sure about making new return uniniialized memory), but the optimizer might see that the initalization is useless and skip it.
The 'might' here is worrying, as the array will be huge and it's really costly to initialize it twice. Is there a way to tell it to not initialize it? Is it safe to use foreach on it if it isn't initialized?
Jan 04 2014
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Sunday, 5 January 2014 at 01:10:29 UTC, Jeroen Bollen wrote:
 Is there a way to tell it to not initialize it?
I'm not sure of any except using the primitives. You can malloc GC memory from GC.malloc (works the same way as C malloc, except you don't have to free it yourself; the GC does it). GC.malloc doesn't initialize the memory. http://dlang.org/phobos/core_memory.html#malloc I don't think there's a way to tell new not to zero it out though...
 Is it safe to use foreach on it if it isn't initialized?
Yeah, the contents will be random, but you are setting it anyway so that doesn't matter.
Jan 04 2014
next sibling parent reply "Jeroen Bollen" <jbinero gmail.com> writes:
Also about the previous C style malloc, to free it, I just use 
the c style delete?
Jan 04 2014
parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Sunday, 5 January 2014 at 01:30:22 UTC, Jeroen Bollen wrote:
 Also about the previous C style malloc, to free it, I just use 
 the c style delete?
free() from core.stdc.stdlib.
Jan 04 2014
prev sibling parent reply "Jeroen Bollen" <jbinero gmail.com> writes:
On Sunday, 5 January 2014 at 01:23:58 UTC, Adam D. Ruppe wrote:
 On Sunday, 5 January 2014 at 01:10:29 UTC, Jeroen Bollen wrote:
 Is there a way to tell it to not initialize it?
I'm not sure of any except using the primitives. You can malloc GC memory from GC.malloc (works the same way as C malloc, except you don't have to free it yourself; the GC does it). GC.malloc doesn't initialize the memory. http://dlang.org/phobos/core_memory.html#malloc I don't think there's a way to tell new not to zero it out though...
 Is it safe to use foreach on it if it isn't initialized?
Yeah, the contents will be random, but you are setting it anyway so that doesn't matter.
As GC.malloc returns a pointer, how does it know when it should garbage collect the allocated space?
Jan 04 2014
parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Sunday, 5 January 2014 at 02:08:56 UTC, Jeroen Bollen wrote:
 As GC.malloc returns a pointer, how does it know when it should 
 garbage collect the allocated space?
The gc keeps track of the size and scans memory for any pointer into the region. If there's none, it collects it.
Jan 04 2014
prev sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Adam D. Ruppe:

 but the optimizer might see that the initalization is useless 
 and skip it.
Currently D compilers seem not good at that. In std.array there are two functions to allocate arrays that are not or not fully initialized to avoid a double initialization. Bye, bearophile
Jan 04 2014
parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Sunday, 5 January 2014 at 02:17:00 UTC, bearophile wrote:
 Currently D compilers seem not good at that. In std.array there 
 are two functions to allocate arrays that are not or not fully 
 initialized to avoid a double initialization.
Oh cool, I forgot to check std.array. Here's the link: http://dlang.org/phobos/std_array.html#uninitializedArray Using that would surely be better than doing it yourself with GC.malloc.
Jan 04 2014
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2014-01-05 01:17, Jeroen Bollen wrote:
 Also a somewhat unrelated question, variables in D get initialized by
 default, do they also when you define them right after? Something like:

 int[] iryy = new int[](50); // Will the array elements be initialized to 0?
Yes, have a look at: http://dlang.org/arrays.html#array-initialization This example verifies the behavior: int[] iryy = new int[](50); assert(iryy[3] == 0); -- /Jacob Carlborg
Jan 05 2014