www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Questions about GC

reply Thomas <vigipe3501 preparmy.com> writes:
Hi, just a couple of questions about how the GC works

1.

if you have an array that doesnt have any pointers like

```
struct Point { double x,y;}

Point[] points;
```

Does the GC still go through and scan them for pointers or does 
the compiler know that it doesn't have to?


2.

if you have an array with a local scope

```
while(something)
{
    int[] xs;

    // do something

}  <-- does it return the memory here for 'xs' for reuse 
instantly since it knows it's unreachable or does it wait for a 
collection event?
```
Jun 22
parent reply "H. S. Teoh" <hsteoh qfbox.info> writes:
On Mon, Jun 22, 2026 at 11:37:56PM +0000, Thomas via Digitalmars-d-learn wrote:
 Hi, just a couple of questions about how the GC works
 
 1.
 
 if you have an array that doesnt have any pointers like
 
 ```
 struct Point { double x,y;}
 
 Point[] points;
 ```
 
 Does the GC still go through and scan them for pointers or does the
 compiler know that it doesn't have to?
Pretty sure such an array would have the NO_SCAN bit set, so the GC won't waste time scanning it. Only blocks that might contain pointers will get scanned.
 2.
 
 if you have an array with a local scope
 
 ```
 while(something)
 {
    int[] xs;
 
    // do something
 
 }  <-- does it return the memory here for 'xs' for reuse instantly
 since it knows it's unreachable or does it wait for a collection
 event?
 ```
It will wait for a collection event. If you don't want that, you could explicitly reuse the array, or use a static (stack-allocated) array. Or skip the GC and call C's malloc / free instead. T -- No! I'm not in denial!
Jun 22
parent reply Thomas <vigipe3501 preparmy.com> writes:
thank you, do you know how to reuse an array? it seems to reset 
the capacity when you set the length to 0, so it reallocates when 
you append to it
```
import std.stdio;
import std.format;

void main()
{
     int[] xs;

     foreach (i ; 0..3)
     {
         format("1: length:%s capacity:%s ptr:%s",xs.length, 
xs.capacity, xs.ptr).writeln;
         xs.length = 0;
         format("2: length:%s capacity:%s ptr:%s",xs.length, 
xs.capacity, xs.ptr).writeln;
         xs ~= i;
         format("3: length:%s capacity:%s ptr:%s",xs.length, 
xs.capacity, xs.ptr).writeln;
         writeln("------------------------");
     }
}
```

gives me
```
1: length:0 capacity:0 ptr:null
2: length:0 capacity:0 ptr:null
3: length:1 capacity:3 ptr:72DECA101020
------------------------
1: length:1 capacity:3 ptr:72DECA101020
2: length:0 capacity:0 ptr:72DECA101020
3: length:1 capacity:3 ptr:72DECA101060
------------------------
1: length:1 capacity:3 ptr:72DECA101060
2: length:0 capacity:0 ptr:72DECA101060
3: length:1 capacity:3 ptr:72DECA1010A0
------------------------
```
Jun 22
parent "H. S. Teoh" <hsteoh qfbox.info> writes:
On Tue, Jun 23, 2026 at 01:03:37AM +0000, Thomas via Digitalmars-d-learn wrote:
 thank you, do you know how to reuse an array? it seems to reset the capacity
 when you set the length to 0, so it reallocates when you append to it
[...] You can do it two ways: 1) Either manually, by setting .length to the desired capacity, and using a separate variable to keep track of its "actual" length; or 2) Use .assumeSafeAppend to tell the runtime to overwrite elements when you append to it, if the allocated block still has capacity. (2) is easier to write, but less efficient as it needs to invoke a runtime function each time, whereas (1) is more efficient, but a bit more fiddly for your code to handle. I've used both approaches before in my code -- it's one of the more common optimizations I use when profiling reveals that the program is spending a lot of time inside the GC. T -- I'm still trying to find a pun for "punishment"...
Jun 22