digitalmars.D - GC pathological case behaviour
- John Colvin (31/31) Jun 28 2016 On my machine (OS X), this program eats up memory with no end in
- deadalnix (6/37) Jun 28 2016 My bet is that you are creating fragmentation in the small size
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (3/7) Jun 28 2016 Try to put locks around the allocations to see if it is a
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (2/5) Jun 28 2016 But wait, is the string zero terminated?
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (3/9) Jun 28 2016 Forget it, it should be.
- Steven Schveighoffer (3/8) Jun 28 2016 I have to laugh at this quoted post :)
- luminousone (4/35) Jun 28 2016 Is puts high enough latency that, that main thread can fill the
- Steven Schveighoffer (5/8) Jun 28 2016 I think this is it. Your main loop is doing very little, basically just
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (5/15) Jun 28 2016 Is the message queue unlimited by default? Use this then:
- Steven Schveighoffer (5/16) Jun 28 2016 It appears so:
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (6/9) Jun 28 2016 I guess it makes sense, as you could get deadlocks for specific
- John Colvin (4/8) Jun 28 2016 It appears that adding a 1ms sleep causes the leak to disappear.
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (5/13) Jun 28 2016 Not necessarily, if the 10K allocations results in system calls,
- Martin Nowak (5/9) Jun 29 2016 Yes your overflowing your MessageBox, nothing the GC can do about
On my machine (OS X), this program eats up memory with no end in sight import std.concurrency; import core.stdc.stdio; void start() { while(true) { receive( (int msg) { char[2] s = '\0'; s[0] = cast(char)msg; puts(s.ptr); // remove this => no memory leak } ); } } void main() { auto hw_tid = spawn(&start); while(true) { send(hw_tid, 64); auto b = new ubyte[](1_000); // 10_000 => no memory leak } } This is very odd, no? I'm not sure if it's a bug, but it sure is surprising. Why should "puts" cause a GC leak (writeln is the same)? What's so special about small allocations that allows all my memory to get filled up?
Jun 28 2016
On Tuesday, 28 June 2016 at 19:03:14 UTC, John Colvin wrote:On my machine (OS X), this program eats up memory with no end in sight import std.concurrency; import core.stdc.stdio; void start() { while(true) { receive( (int msg) { char[2] s = '\0'; s[0] = cast(char)msg; puts(s.ptr); // remove this => no memory leak } ); } } void main() { auto hw_tid = spawn(&start); while(true) { send(hw_tid, 64); auto b = new ubyte[](1_000); // 10_000 => no memory leak } } This is very odd, no? I'm not sure if it's a bug, but it sure is surprising. Why should "puts" cause a GC leak (writeln is the same)? What's so special about small allocations that allows all my memory to get filled up?My bet is that you are creating fragmentation in the small size allocator. 10 000 is hitting the larg size one, whihc doesn't seems to have the same problem. Now that would explain extra memory consumption, but I'm not sure why this wouldn't allow things to be freed at the end anyway.
Jun 28 2016
On Tuesday, 28 June 2016 at 19:03:14 UTC, John Colvin wrote:This is very odd, no? I'm not sure if it's a bug, but it sure is surprising. Why should "puts" cause a GC leak (writeln is the same)? What's so special about small allocations that allows all my memory to get filled up?Try to put locks around the allocations to see if it is a race-condition.
Jun 28 2016
On Tuesday, 28 June 2016 at 19:03:14 UTC, John Colvin wrote:char[2] s = '\0'; s[0] = cast(char)msg; puts(s.ptr); // remove this => no memory leakBut wait, is the string zero terminated?
Jun 28 2016
On Tuesday, 28 June 2016 at 19:53:27 UTC, Ola Fosheim Grøstad wrote:On Tuesday, 28 June 2016 at 19:03:14 UTC, John Colvin wrote:Forget it, it should be.char[2] s = '\0'; s[0] = cast(char)msg; puts(s.ptr); // remove this => no memory leakBut wait, is the string zero terminated?
Jun 28 2016
On 6/28/16 3:53 PM, Ola Fosheim Grøstad wrote:On Tuesday, 28 June 2016 at 19:03:14 UTC, John Colvin wrote:I have to laugh at this quoted post :) -Stevechar[2] s = '\0'; s[0] = cast(char)msg; puts(s.ptr); // remove this => no memory leakBut wait, is the string zero terminated?
Jun 28 2016
On Tuesday, 28 June 2016 at 19:03:14 UTC, John Colvin wrote:On my machine (OS X), this program eats up memory with no end in sight import std.concurrency; import core.stdc.stdio; void start() { while(true) { receive( (int msg) { char[2] s = '\0'; s[0] = cast(char)msg; puts(s.ptr); // remove this => no memory leak } ); } } void main() { auto hw_tid = spawn(&start); while(true) { send(hw_tid, 64); auto b = new ubyte[](1_000); // 10_000 => no memory leak } } This is very odd, no? I'm not sure if it's a bug, but it sure is surprising. Why should "puts" cause a GC leak (writeln is the same)? What's so special about small allocations that allows all my memory to get filled up?Is puts high enough latency that, that main thread can fill the message queue faster then start can exhaust it? If you put a call to sleep for 1ms in the main loop does it have the same result?
Jun 28 2016
On 6/28/16 4:12 PM, luminousone wrote:Is puts high enough latency that, that main thread can fill the message queue faster then start can exhaust it? If you put a call to sleep for 1ms in the main loop does it have the same result?I think this is it. Your main loop is doing very little, basically just allocating memory. The child thread is putting data to the console, which is much more expensive. -Steve
Jun 28 2016
On Tuesday, 28 June 2016 at 20:24:33 UTC, Steven Schveighoffer wrote:On 6/28/16 4:12 PM, luminousone wrote:Is the message queue unlimited by default? Use this then: https://dlang.org/phobos/std_concurrency.html#.setMaxMailboxSize ?Is puts high enough latency that, that main thread can fill the message queue faster then start can exhaust it? If you put a call to sleep for 1ms in the main loop does it have the same result?I think this is it. Your main loop is doing very little, basically just allocating memory. The child thread is putting data to the console, which is much more expensive.
Jun 28 2016
On 6/28/16 4:35 PM, Ola Fosheim Grøstad wrote:On Tuesday, 28 June 2016 at 20:24:33 UTC, Steven Schveighoffer wrote:It appears so: https://github.com/dlang/phobos/blob/master/std/concurrency.d#L2164 m_maxMsgs is default 0. -SteveOn 6/28/16 4:12 PM, luminousone wrote:Is the message queue unlimited by default?Is puts high enough latency that, that main thread can fill the message queue faster then start can exhaust it? If you put a call to sleep for 1ms in the main loop does it have the same result?I think this is it. Your main loop is doing very little, basically just allocating memory. The child thread is putting data to the console, which is much more expensive.
Jun 28 2016
On Tuesday, 28 June 2016 at 21:19:18 UTC, Steven Schveighoffer wrote:It appears so: https://github.com/dlang/phobos/blob/master/std/concurrency.d#L2164 m_maxMsgs is default 0.I guess it makes sense, as you could get deadlocks for specific restrictions, although I personally would side with forcing the programmer to specify the buffering policies rather than providing defaults.
Jun 28 2016
On Tuesday, 28 June 2016 at 20:12:29 UTC, luminousone wrote:Is puts high enough latency that, that main thread can fill the message queue faster then start can exhaust it? If you put a call to sleep for 1ms in the main loop does it have the same result?It appears that adding a 1ms sleep causes the leak to disappear. Still seems like bad behaviour from the GC though, perhaps indicative of a bug.
Jun 28 2016
On Tuesday, 28 June 2016 at 21:01:20 UTC, John Colvin wrote:On Tuesday, 28 June 2016 at 20:12:29 UTC, luminousone wrote:Not necessarily, if the 10K allocations results in system calls, but try to remove the 1ms delay, set setMaxMailboxSize to a millon and set it to ignore. (i.e. if the box is full you bypass sending).Is puts high enough latency that, that main thread can fill the message queue faster then start can exhaust it? If you put a call to sleep for 1ms in the main loop does it have the same result?It appears that adding a 1ms sleep causes the leak to disappear. Still seems like bad behaviour from the GC though, perhaps indicative of a bug.
Jun 28 2016
On Tuesday, 28 June 2016 at 21:20:01 UTC, Ola Fosheim Grøstad wrote:Not necessarily, if the 10K allocations results in system calls, but try to remove the 1ms delay, set setMaxMailboxSize to a millon and set it to ignore. (i.e. if the box is full you bypass sending).Yes your overflowing your MessageBox, nothing the GC can do about that. BTW, try --DRT-gcopt=profile:2 or so.
Jun 29 2016