digitalmars.D.learn - Garbage collection and closures.
- ANtlord (12/12) Jun 17 2017 Hello! I can't understand one thing related to closures and
- Adam D. Ruppe (14/15) Jun 17 2017 No, it will once on scope entry; where the deepest-referenced
- ANtlord (8/16) Jun 17 2017 Excuse me, I can't get what does it mean "deepest-referenced".
- Adam D. Ruppe (22/28) Jun 17 2017 Where the variable is defined that is referenced in the closure.
- ANtlord (10/38) Jun 17 2017 Thanks a lot, Adam! Everything is clear. Except for the bug. I've
- Dsby (4/9) Jun 19 2017 if the uses parma is 'scope':
- Dsby (30/43) Jun 19 2017 I test it , if use scope it will not alloc memony.
- Adam D. Ruppe (3/7) Jun 19 2017 Right, using `scope` at the point the delegate variable is
Hello! I can't understand one thing related to closures and calling of GC. I have the following demo snippet, where a closure is passed to `receive` function in a loop. bool isDone = false; while(!isDone) receive((bool val){ isDone = val }); Is GC called every iteration of this loop? I know that I can move the code to a method of a struct and make the closure and variable "isDone" as fields of the struct. It avoids GC calling definitely. But I want to get how many times GC is called in case of a closure in a loop. Thanks.
Jun 17 2017
On Saturday, 17 June 2017 at 13:03:28 UTC, ANtlord wrote:Is GC called every iteration of this loop?No, it will once on scope entry; where the deepest-referenced variable that is actually captured is defined. The compiler allocates heap space instead of stack space for the locals, then runs the function normally using that space. The current implementation doesn't quite do this - it actually will alloc only once, on function entry, even when there's a variable inside a loop that is supposed to be independent. This is the cause of the commonly-referenced bug with foreach(i; whatever) capture(i); all showing the same number. When that bug is fixed, it is possible to allocate on each loop... but your code doesn't anyway, so you're ok. It will only alloc once. You can prove this with a debugger btw, set a breakpoint on `_d_allocmemory`.
Jun 17 2017
On Saturday, 17 June 2017 at 13:13:17 UTC, Adam D. Ruppe wrote:On Saturday, 17 June 2017 at 13:03:28 UTC, ANtlord wrote:Excuse me, I can't get what does it mean "deepest-referenced". What the deep you mean? The deep of a closure or deep of the function where the variable is defined. Can you give an example code?Is GC called every iteration of this loop?No, it will once on scope entry; where the deepest-referenced variable that is actually captured is defined. The compiler allocates heap space instead of stack space for the locals, then runs the function normally using that space.It will only alloc once. You can prove this with a debugger btw, set a breakpoint on `_d_allocmemory`.Is this function called every time when allocation happens in a heap? Thank you. Sorry if my English is not clear.
Jun 17 2017
On Saturday, 17 June 2017 at 14:19:34 UTC, ANtlord wrote:Excuse me, I can't get what does it mean "deepest-referenced". What the deep you mean? The deep of a closure or deep of the function where the variable is defined. Can you give an example code?Where the variable is defined that is referenced in the closure. So: --- void uses(void delegate() dg); void foo() { int a; foreach(b; 0 .. 10) { } } --- the foo() function. It only uses `a`, so it doesn't have to allocate again after the point a is defined. doesn't, but this is filed as an open bug because it is supposed to.) Since it uses `b` which is defined inside the loop, it will have to allocate a new copy for each iteration.Is this function called every time when allocation happens in a heap?Not any allocation, it is just the function the compiler uses when it needs to make a closure.
Jun 17 2017
On Saturday, 17 June 2017 at 17:15:50 UTC, Adam D. Ruppe wrote:On Saturday, 17 June 2017 at 14:19:34 UTC, ANtlord wrote:Thanks a lot, Adam! Everything is clear. Except for the bug. I've value equals to number from sequence plus one in each iteration. There are ten iterations. What's wrong? Are there should be five iterations? It doesn't make sense for me due to the variable assigned value from the sequence 0..10. Or do I look at the wrong place? Can you give me a link to the bug? Thank you again!Excuse me, I can't get what does it mean "deepest-referenced". What the deep you mean? The deep of a closure or deep of the function where the variable is defined. Can you give an example code?Where the variable is defined that is referenced in the closure. So: --- void uses(void delegate() dg); void foo() { int a; foreach(b; 0 .. 10) { } } --- the foo() function. It only uses `a`, so it doesn't have to allocate again after the point a is defined. doesn't, but this is filed as an open bug because it is supposed to.) Since it uses `b` which is defined inside the loop, it will have to allocate a new copy for each iteration.Is this function called every time when allocation happens in a heap?Not any allocation, it is just the function the compiler uses when it needs to make a closure.
Jun 17 2017
On Saturday, 17 June 2017 at 17:15:50 UTC, Adam D. Ruppe wrote:On Saturday, 17 June 2017 at 14:19:34 UTC, ANtlord wrote:if the uses parma is 'scope': void uses(scope void delegate() dg); will it be not alloc memory?[...]Where the variable is defined that is referenced in the closure. So: [...]
Jun 19 2017
On Monday, 19 June 2017 at 09:10:16 UTC, Dsby wrote:On Saturday, 17 June 2017 at 17:15:50 UTC, Adam D. Ruppe wrote:I test it , if use scope it will not alloc memony. import std.stdio; void call(void delegate() fun) { fun(); } void call2(scope void delegate() fun) { fun(); } void main() { int a = 10; // call((){writeln(a);}); call2((){writeln(a);}); } dmd -vgc ./t.d it will not print anything. if use call: void main() { int a = 10; call((){writeln(a);}); // call2((){writeln(a);}); } dmd -vgc ./t.d 182ms 2017年06月19日 星期一 17时16分47秒 ./t.d(13): vgc: using closure causes GC allocationOn Saturday, 17 June 2017 at 14:19:34 UTC, ANtlord wrote:if the uses parma is 'scope': void uses(scope void delegate() dg); will it be not alloc memory?[...]Where the variable is defined that is referenced in the closure. So: [...]
Jun 19 2017
On Monday, 19 June 2017 at 09:18:56 UTC, Dsby wrote:Right, using `scope` at the point the delegate variable is defined means it will never allocate.void uses(scope void delegate() dg); will it be not alloc memory?I test it , if use scope it will not alloc memony.
Jun 19 2017