digitalmars.D.learn - Dynamic Array Question
- Dax (20/20) Sep 20 2011 Hi!
- Steven Schveighoffer (26/48) Sep 20 2011 No, in a GC-enabled language, the GC is responsible for cleaning up the ...
- travert phare.normalesup.org (Christophe) (1/15) Sep 20 2011 does "scope wchar[] t = ...;" work too ?
- Jonathan M Davis (7/23) Sep 20 2011 I'm not sure, but scope as a modifier on local variables like that is go...
- Jesse Phillips (2/12) Sep 20 2011 Unless I missed something, delete is being removed from the language.
- Steven Schveighoffer (5/17) Sep 22 2011 Note: ^^^^^^^^^^^^^^^^^^^^^^^^^
- Jonathan M Davis (15/41) Sep 20 2011 You don't deallocate dynamic arrays. The GC manages them. The GC manages...
- Timon Gehr (5/23) Sep 20 2011 Does it 'leak'? What is your exact setup, why isn't the GC collecting
- Dax (9/11) Sep 20 2011 I have a Label class with a text() property that calls the procedure
Hi! I'm working on a library written in D. After some tests I have discovered that my library leaks memory, those leaks are caused by dynamics array that I use in my library. My question is: Should dynamics array be deallocated automatically when a procedure returns? There is another way to acomplish this? Maybe I'm doing something wrong, so, I post the function that causes the leak: public string getWindowText(HWND hWnd) { int len = GetWindowTextLengthW(hWnd); wchar[] t = new wchar[len + 1]; // How to deallocate this? GetWindowTextW(hWnd, t.ptr, len); /* * I'm converting the wchar[] to char[], * the variable 't' should be deallocated * because I not need it anymore. */ return to!(string)(t[0..len]); } Thanks, Dax
Sep 20 2011
On Tue, 20 Sep 2011 14:06:34 -0400, Dax <dax mailinator.com> wrote:Hi! I'm working on a library written in D. After some tests I have discovered that my library leaks memory, those leaks are caused by dynamics array that I use in my library. My question is: Should dynamics array be deallocated automatically when a procedure returns?No, in a GC-enabled language, the GC is responsible for cleaning up the memory.There is another way to acomplish this?Yes, you can manually free the memory at your own risk. Note that in any GC-enabled language, more memory is consumed than in a manually-managed language. This is because there is a time period where a memory block is unused, but still allocated (i.e. the GC hasn't collected it yet). D's garbage collector is conservative, which means it may keep some blocks in memory even though they are no longer in use. Also, depending on your measurement tools, you may be counting freed memory towards memory usage. For example, if a block of memory is deallocated, it's not given back to the OS, it simply goes back into a pool to be reallocated again later.Maybe I'm doing something wrong, so, I post the function that causes the leak: public string getWindowText(HWND hWnd) { int len = GetWindowTextLengthW(hWnd); wchar[] t = new wchar[len + 1]; // How to deallocate this? GetWindowTextW(hWnd, t.ptr, len); /* * I'm converting the wchar[] to char[], * the variable 't' should be deallocated * because I not need it anymore. */ return to!(string)(t[0..len]); }You can deallocate the original array. The soon-to-be-deprecated method (but easiest) is: delete t; To avoid having to change your other code, I'd do this: wchar[] t = ...; scope(exit) delete t; // add this line to the end of the function (after returning) There is another way, but it's not as easy: // put this at the top of file import core.memory; ... scope(exit) GC.free(t.ptr); However, this is what will be required when delete is deprecated. -Steve
Sep 20 2011
To avoid having to change your other code, I'd do this: wchar[] t = ...; scope(exit) delete t; // add this line to the end of the function (after returning) There is another way, but it's not as easy: // put this at the top of file import core.memory; ... scope(exit) GC.free(t.ptr);does "scope wchar[] t = ...;" work too ?
Sep 20 2011
On Tuesday, September 20, 2011 21:48:10 Christophe wrote:I'm not sure, but scope as a modifier on local variables like that is going to be removed from the language. std.typecons.Scoped is replacing it. However, unless you're having major memory issues, I really wouldn't worry about it. Just let the garbage collector do its thing. It's not the best, but it works fine in most cases. - Jonathan M DavisTo avoid having to change your other code, I'd do this: wchar[] t = ...; scope(exit) delete t; // add this line to the end of the function (after returning) There is another way, but it's not as easy: // put this at the top of file import core.memory; ... scope(exit) GC.free(t.ptr);does "scope wchar[] t = ...;" work too ?
Sep 20 2011
On Tue, 20 Sep 2011 14:28:54 -0400, Steven Schveighoffer wrote:You can deallocate the original array. The soon-to-be-deprecated method (but easiest) is: delete t; To avoid having to change your other code, I'd do this: wchar[] t = ...; scope(exit) delete t; // add this line to the end of the function (after returning)Unless I missed something, delete is being removed from the language.
Sep 20 2011
On Wed, 21 Sep 2011 00:09:08 -0400, Jesse Phillips <jessekphillips+d gmail.com> wrote:On Tue, 20 Sep 2011 14:28:54 -0400, Steven Schveighoffer wrote:Note: ^^^^^^^^^^^^^^^^^^^^^^^^^ :)You can deallocate the original array. The soon-to-be-deprecated method-Steve(but easiest) is: delete t; To avoid having to change your other code, I'd do this: wchar[] t = ...; scope(exit) delete t; // add this line to the end of the function (after returning)Unless I missed something, delete is being removed from the language.
Sep 22 2011
On Tuesday, September 20, 2011 11:06 Dax wrote:Hi! I'm working on a library written in D. After some tests I have discovered that my library leaks memory, those leaks are caused by dynamics array that I use in my library. My question is: Should dynamics array be deallocated automatically when a procedure returns? There is another way to acomplish this? Maybe I'm doing something wrong, so, I post the function that causes the leak: public string getWindowText(HWND hWnd) { int len = GetWindowTextLengthW(hWnd); wchar[] t = new wchar[len + 1]; // How to deallocate this? GetWindowTextW(hWnd, t.ptr, len); /* * I'm converting the wchar[] to char[], * the variable 't' should be deallocated * because I not need it anymore. */ return to!(string)(t[0..len]); }You don't deallocate dynamic arrays. The GC manages them. The GC manages all of the memory that you allocate in D with new. If the memory gets freed, it gets freed during a garbage collection cycle. When the GC runs is non- deterministic. I believe that it normally only ever gets called when new is called, and it's only going to run when new is called if it thinks that it needs to run. The fact that your program doesn't reference a chunk of memory anymore is irrelevant until a garbage collection cycle runs. That memory won't be freed until then. However last I heard, the GC still never released memory to the OS, and if that's still true, even if the GC collects the memory so that your program can reuse it, the memory usage of your program will never actually go down. So, if what you're doing is looking at the memory usage of your program, that may never go down regardless. - Jonathan M Davis
Sep 20 2011
On 09/20/2011 08:06 PM, Dax wrote:Hi! I'm working on a library written in D. After some tests I have discovered that my library leaks memory, those leaks are caused by dynamics array that I use in my library.Does it 'leak'? What is your exact setup, why isn't the GC collecting that memory?My question is: Should dynamics array be deallocated automatically when a procedure returns? There is another way to acomplish this? Maybe I'm doing something wrong, so, I post the function that causes the leak: public string getWindowText(HWND hWnd) { int len = GetWindowTextLengthW(hWnd); wchar[] t = new wchar[len + 1]; // How to deallocate this? GetWindowTextW(hWnd, t.ptr, len); /* * I'm converting the wchar[] to char[], * the variable 't' should be deallocated * because I not need it anymore. */ return to!(string)(t[0..len]); }Unless the string gets extremely long, you could allocate it on the stack: wchar[] t=(cast(wchar*)alloca(wchar.sizeof*(len+1)))[0..len+1];
Sep 20 2011
Does it 'leak'? What is your exact setup, why isn't the GC collecting that memory?I have a Label class with a text() property that calls the procedure that I have written in my first post and returns the result. I have posted here because I was looking the memory usage (more precisely the process' private working set) with Process Explorer (from Sysinternals) and I saw the private working set increase and increase every time text() property il called, so I trought it was a memory leak. But, if the Garbage Collector handles the memory allocation of dynamic arrays, the problem is solved. Thanks to all for help me with this problem! :)
Sep 20 2011