December 27, 2012 Re: Running out of memory | ||||
|---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 2012-12-27 16:31, bearophile wrote: > Don't cast arrays arrays to pointers, it's unclean, because dynamic arrays are > two words long. Use the .ptr property: > > GC.free(s.ptr); Things appeared sorted out, but it's not over yet. delete still wins. Performance-wise free() worked like delete, but there's a nasty glitch. The following code crashes after a few hundred loops with core.exception.InvalidMemoryOperationError. import std.stdio, core.memory; char[1000] filler = '.'; int fill_times = 10000; void main(string[] args) { char[] s; for (int i=0; i < 100000; i++) { for (int j=0; j < fill_times; j++) s ~= filler; writeln("loop ", i + 1, ", length: ", s.length); stdout.flush(); // delete s; GC.free(s.ptr); s = []; } } Surprisingly, when fill_times >= 3736, it always crashes after the 341th loop (relies on the filler having 1000 bytes. Some other numbers also trigger it). What could be responsible for this odd behavior of free()? | |||
December 28, 2012 Re: Running out of memory | ||||
|---|---|---|---|---|
| ||||
Posted in reply to FG | On Thursday, December 27, 2012 16:00:58 FG wrote:
> On 2012-12-27 15:31, bearophile wrote:
> > delete is deprecated in D. There is destroy(), and a replacement for
> > delete in the memory/GC module.
>
> destroy() had no effect on program's behavior, even the docs state that "it
> does not initiate a GC cycle or free any GC memory".
> So I hope delete will still remain an option.
> Very useful for freeing such large chunks like in this example.
>
> What do you mean as the delete replacement?
The idea is that if you want to be manually freeing memory, you shouldn't be using GC memory in the first place. It's unsafe to be freeing it. Let the GC do that. If you want to manually manage memory, then manually manage it with malloc and free. If you really need to, then core.memory has the functions for managing the GC's memory, but you really shouldn't be doing that normally.
Manual memory management should become easier once custom allocators are sorted out, since right now, if you want objects, you need to use emplace to turn the malloced memory into a proper object, and it's definitely more of a pain than using new with the GC. But it's still not a good idea in general to try and do manual memory management on GC memory.
- Jonathan M Davis
| |||
December 28, 2012 Re: Running out of memory | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On 2012-12-28 05:41, Jonathan M Davis wrote:
> The idea is that if you want to be manually freeing memory, you shouldn't be
> using GC memory in the first place. It's unsafe to be freeing it. Let the GC do
> that. If you want to manually manage memory, then manually manage it with
> malloc and free. If you really need to, then core.memory has the functions for
> managing the GC's memory, but you really shouldn't be doing that normally.
I don't require manual malloc. I wanted to make a hint to the GC, that this block can be freed, because I know there are no other pointers into it (that would be used later), while the imprecise GC finds false pointers and prevents the block from being released.
Of course delete is not safe in general, but if the program is designed to process data in completely isolated batches, then it shouldn't pose a threat.
| |||
December 28, 2012 Re: Running out of memory | ||||
|---|---|---|---|---|
| ||||
Posted in reply to FG | On Friday, 28 December 2012 at 10:40:32 UTC, FG wrote:
> I don't require manual malloc. I wanted to make a hint to the GC, that this block can be freed, because I know there are no other pointers into it (that would be used later), while the imprecise GC finds false pointers and prevents the block from being released.
set to null + GC.collect()? but of course it shouldn't be used careless too
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply