digitalmars.D.learn - want to confirm: gc will not free a non-gc-allocated field of a
- mw (23/23) Jun 06 2022 Hi,
- max haughton (3/27) Jun 06 2022 float[] doesn't contain pointers, so the GC won't do anything to
- mw (5/7) Jun 06 2022 does every array have a .ptr attr?
- ag0aep6g (4/6) Jun 06 2022 wat
- max haughton (16/22) Jun 06 2022 I'm talking about the data in the array.
- ag0aep6g (2/5) Jun 07 2022 That wasn't mw's question.
- max haughton (8/14) Jun 07 2022 I also answered this in my original one IIRC. There's nothing too
- ag0aep6g (3/7) Jun 07 2022 You didn't.
- max haughton (2/9) Jun 07 2022 Ok I must have assumed it was obvious it wouldn't free it.
- Guillaume Piolat (8/13) Jun 06 2022 My understanding is that while scanning, the GC will see the
- Guillaume Piolat (4/11) Jun 06 2022 In D, the ownership of slice is purely determined by the memory
- H. S. Teoh (25/52) Jun 06 2022 [...]
- Steven Schveighoffer (11/37) Jun 07 2022 Others have given answers on this, but I just want to clarify -- the GC
- mw (3/6) Jun 07 2022 Thanks for the detailed explanation, and everyone who has replied.
Hi, Suppose I have this code: ``` class GCAllocated { float[] data; this() { // non-gc-allocated field this.data = cast(float[])(core.stdc.stdlib.malloc(nBytes)[0 .. nBytes]); } } void foo() { auto obj = new GCAllocated(); // gc-allocated owning object ... } ``` So when `obj` is cleanup by the GC, obj.data won't be freed by the GC: because the `data` is non-gc-allocated (and it's allocated on the non-gc heap), the GC scanner will just skip that field during a collection scan. Is this understanding correct? I need this behavior for a special purpose, so I want to confirm it. Thanks.
Jun 06 2022
On Monday, 6 June 2022 at 22:18:08 UTC, mw wrote:Hi, Suppose I have this code: ``` class GCAllocated { float[] data; this() { // non-gc-allocated field this.data = cast(float[])(core.stdc.stdlib.malloc(nBytes)[0 .. nBytes]); } } void foo() { auto obj = new GCAllocated(); // gc-allocated owning object ... } ``` So when `obj` is cleanup by the GC, obj.data won't be freed by the GC: because the `data` is non-gc-allocated (and it's allocated on the non-gc heap), the GC scanner will just skip that field during a collection scan. Is this understanding correct? I need this behavior for a special purpose, so I want to confirm it. Thanks.float[] doesn't contain pointers, so the GC won't do anything to or with it.
Jun 06 2022
On Monday, 6 June 2022 at 22:22:05 UTC, max haughton wrote:float[] doesn't contain pointers, so the GC won't do anything to or with it.does every array have a .ptr attr? https://dlang.org/spec/arrays.html Dynamic Array Properties .ptr Returns a pointer to the first element of the array.
Jun 06 2022
On 07.06.22 00:22, max haughton wrote:float[] doesn't contain pointers, so the GC won't do anything to or with it.wat float[] is a pointer (plus a length). The GC will deal with it like any other pointer.
Jun 06 2022
On Tuesday, 7 June 2022 at 00:40:56 UTC, ag0aep6g wrote:On 07.06.22 00:22, max haughton wrote:I'm talking about the data in the array. void[] might contain pointers, float[] does not so it won't be scanned. Or at least shouldn't be... This is why you shouldn't use void[] for everything if you can help it. ``` void main() { import std.stdio; auto voidArray = typeid(void[]); auto floatArray = typeid(float[]); writeln(voidArray.next.flags() & 1 ); writeln(floatArray.next.flags() & 1); } ```float[] doesn't contain pointers, so the GC won't do anything to or with it.wat float[] is a pointer (plus a length). The GC will deal with it like any other pointer.
Jun 06 2022
On 07.06.22 03:02, max haughton wrote:I'm talking about the data in the array. void[] might contain pointers, float[] does not so it won't be scanned.That wasn't mw's question.
Jun 07 2022
On Tuesday, 7 June 2022 at 08:56:29 UTC, ag0aep6g wrote:On 07.06.22 03:02, max haughton wrote:I also answered this in my original one IIRC. There's nothing too free because the GC didn't allocate it. Every allocator needs to either have a GC or a fast way to free memory which includes checking whether it owns memory in the first place. annoyingly you can't express this in the malloc/free pattern very well at all. One of the many gifts C has given the world.I'm talking about the data in the array. void[] might contain pointers, float[] does not so it won't be scanned.That wasn't mw's question.
Jun 07 2022
On 07.06.22 11:00, max haughton wrote:On Tuesday, 7 June 2022 at 08:56:29 UTC, ag0aep6g wrote:[...]You didn't.That wasn't mw's question.I also answered this in my original one IIRC.
Jun 07 2022
On Tuesday, 7 June 2022 at 09:12:25 UTC, ag0aep6g wrote:On 07.06.22 11:00, max haughton wrote:Ok I must have assumed it was obvious it wouldn't free it.On Tuesday, 7 June 2022 at 08:56:29 UTC, ag0aep6g wrote:[...]You didn't.That wasn't mw's question.I also answered this in my original one IIRC.
Jun 07 2022
On Monday, 6 June 2022 at 22:18:08 UTC, mw wrote:So when `obj` is cleanup by the GC, obj.data won't be freed by the GC: because the `data` is non-gc-allocated (and it's allocated on the non-gc heap), the GC scanner will just skip that field during a collection scan. Is this understanding correct?My understanding is that while scanning, the GC will see the data.ptr pointer, but will not scan the area it points to since it's not in a GC range (the runtime can distinguish managed pointer and other pointers). After scanning, when obj is non-reachable, the GC will destroy it but that won't lead to a reclaim of data.ptr since it knows it doesn't own that.
Jun 06 2022
On Monday, 6 June 2022 at 22:24:45 UTC, Guillaume Piolat wrote:My understanding is that while scanning, the GC will see the data.ptr pointer, but will not scan the area it points to since it's not in a GC range (the runtime can distinguish managed pointer and other pointers). After scanning, when obj is non-reachable, the GC will destroy it but that won't lead to a reclaim of data.ptr since it knows it doesn't own that.In D, the ownership of slice is purely determined by the memory area it points to. If it points into GC memory then it's a GC slice.
Jun 06 2022
On Mon, Jun 06, 2022 at 10:18:08PM +0000, mw via Digitalmars-d-learn wrote:Hi, Suppose I have this code: ``` class GCAllocated { float[] data; this() { // non-gc-allocated field this.data = cast(float[])(core.stdc.stdlib.malloc(nBytes)[0 .. nBytes]); } } void foo() { auto obj = new GCAllocated(); // gc-allocated owning object ... } ``` So when `obj` is cleanup by the GC, obj.data won't be freed by the GC: because the `data` is non-gc-allocated (and it's allocated on the non-gc heap), the GC scanner will just skip that field during a collection scan. Is this understanding correct? I need this behavior for a special purpose, so I want to confirm it.[...] Short answer: yes, the GC will not do anything with that field. Long answer: even if the GC wanted to do something about that field, how could it? It has no information about how it was allocated. As far as the GC is concerned, it's just a pointer + size pair, just like any other array, and the pointer happens to point outside of GC-allocated memory. Beyond that, the GC knows nothing else about the pointer. Is it allocated by malloc? Is it pointing to static memory? Is it some user-defined custom allocator? Is it some random garbage value? Who knows. The GC knows nothing about the pointer, so it conservatively ignores it. On a more general implementational note, D's GC is conservative, meaning that if an aligned pointer-sized value looks like it might be a pointer value, the GC will assume, erring on the side of being overly cautious, that it *is* a pointer value, and mark any GC memory that it might happen to point to as live. The value could be an int or long, and the GC wouldn't know any better. (More recent precise implementations may skip some of these false positives, though.) The same principle applies, though: if the pointer has a value that the GC doesn't know about (i.e., doesn't point to any of the known GC blocks) then the GC will conservatively just ignore it. T -- Give a man a fish, and he eats once. Teach a man to fish, and he will sit forever.
Jun 06 2022
On 6/6/22 6:18 PM, mw wrote:Hi, Suppose I have this code: ``` class GCAllocated { float[] data; this() { // non-gc-allocated field this.data = cast(float[])(core.stdc.stdlib.malloc(nBytes)[0 .. nBytes]); } } void foo() { auto obj = new GCAllocated(); // gc-allocated owning object ... } ``` So when `obj` is cleanup by the GC, obj.data won't be freed by the GC: because the `data` is non-gc-allocated (and it's allocated on the non-gc heap), the GC scanner will just skip that field during a collection scan. Is this understanding correct?Others have given answers on this, but I just want to clarify -- the GC does *not* use any type information to scan for pointers. The default GC has one bit to tell it whether a block contains pointers or not (if true, it will treat every word as if it were a pointer), and it does not understand array references, just pointers. The precise GC has a bitmap of which words in the block are pointers, and it also does not understand array references. So you are safe, it will see the pointer inside the array reference, and see that it doesn't point at GC memory, so nothing further will be done. -Steve
Jun 07 2022
On Tuesday, 7 June 2022 at 13:56:23 UTC, Steven Schveighoffer wrote:So you are safe, it will see the pointer inside the array reference, and see that it doesn't point at GC memory, so nothing further will be done.Thanks for the detailed explanation, and everyone who has replied.
Jun 07 2022