View Problem Report: 8963
Audit Trail:
From: Eli Barzilay <eli@barzilay.org>
To: pbewig@gmail.com, bugs@plt-scheme.org
Cc: matthias@plt-scheme.org, sk@plt-scheme.org, mflatt@plt-scheme.org,
robby@plt-scheme.org, clements@plt-scheme.org, jay@plt-scheme.org,
meunier@plt-scheme.org, sowens@plt-scheme.org, kathyg@plt-scheme.org,
awick@plt-scheme.org, jacobm@plt-scheme.org, cce@plt-scheme.org,
dalev@plt-scheme.org, samth@plt-scheme.org, ryanc@plt-scheme.org
Subject: Re: [plt-bug] all/8963: Space leak in infinite streams
Date: Mon, 24 Sep 2007 16:05:05 -0400
On Sep 24, pbewig@gmail.com wrote:
> Reported by Phil Bewig for release: 360
> [...]
> I am working on a sequel to my SRFI-40 on streams. The following
> program causes a space leak in PLT but not Chez: [...]
That's most likely due to the conservative GC in 360, which is easy to
trip with lazy code. The thing that happens is that you get a very
long chain of promises, each one points to the next; all you need is
one conservative mistake of the GC which makes it think that some
promise is not GCable, and that holds many other promises.
If my guess is correct, then switching to 370 (which defaults to a
precise GC) will make the problem go away.
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://www.barzilay.org/ Maze is Life!
From: Matthew Flatt <mflatt@cs.utah.edu>
To: Eli Barzilay <eli@barzilay.org>
Cc: pbewig@gmail.com, bugs@plt-scheme.org
Subject: Re: [plt-bug] all/8963: Space leak in infinite streams
Date: Mon, 24 Sep 2007 14:13:27 -0600
At Mon, 24 Sep 2007 16:05:05 -0400, Eli Barzilay wrote:
> On Sep 24, pbewig@gmail.com wrote:
> > Reported by Phil Bewig for release: 360
> > [...]
> > I am working on a sequel to my SRFI-40 on streams. The following
> > program causes a space leak in PLT but not Chez: [...]
>
> That's most likely due to the conservative GC in 360, which is easy to
> trip with lazy code.
No, the example still grows in the latest. I don't immediately the
source of the problem, though.
A slightly smaller example is
(stream-ref (stream-filter
(lambda (x) (zero? x))
(stream-from 0))
1)
If you change the `(zero? x)' to #f, then the program runs in constant
space.
Matthew
From: Eli Barzilay <eli@barzilay.org>
To: Matthew Flatt <mflatt@cs.utah.edu>
Cc: pbewig@gmail.com, bugs@plt-scheme.org
Subject: Re: [plt-bug] all/8963: Space leak in infinite streams
Date: Mon, 24 Sep 2007 16:19:39 -0400
On Sep 24, Matthew Flatt wrote:
> At Mon, 24 Sep 2007 16:05:05 -0400, Eli Barzilay wrote:
> > On Sep 24, pbewig@gmail.com wrote:
> > > Reported by Phil Bewig for release: 360
> > > [...]
> > > I am working on a sequel to my SRFI-40 on streams. The following
> > > program causes a space leak in PLT but not Chez: [...]
> >
> > That's most likely due to the conservative GC in 360, which is easy to
> > trip with lazy code.
>
> No, the example still grows in the latest. I don't immediately the
> source of the problem, though.
Another possible issue is that he's using srfi-45's delay, and I think
that there were some changes to that code that didn't get through to
the PLT version. But this:
> A slightly smaller example is
>
> (stream-ref (stream-filter
> (lambda (x) (zero? x))
> (stream-from 0))
> 1)
>
> If you change the `(zero? x)' to #f, then the program runs in
> constant space.
sounds like a real problem...
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://www.barzilay.org/ Maze is Life!
From: Eli Barzilay <eli@barzilay.org>
To: Matthew Flatt <mflatt@cs.utah.edu>
Cc: pbewig@gmail.com, bugs@plt-scheme.org
Subject: Re: [plt-bug] all/8963: Space leak in infinite streams
Date: Mon, 24 Sep 2007 16:29:28 -0400
On Sep 24, Matthew Flatt wrote:
> [...]
> A slightly smaller example is
>
> (stream-ref (stream-filter
> (lambda (x) (zero? x))
> (stream-from 0))
> 1)
>
> If you change the `(zero? x)' to #f, then the program runs in constant
> space.
The same thing happens with lazy:
(define (from n) (cons n (from (add1 n))))
(list-ref (filter zero? (from 0)) 1)
takes more and more memory, and using (lambda (x) #f) does not. This
is also fine:
(list-ref (filter zero? (from 1)) 1)
I'd suspect some problem in my `filter', but that doesn't explain how
chez runs fine with the above. (With Phil's code.)
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://www.barzilay.org/ Maze is Life!
From: Eli Barzilay <eli@barzilay.org>
To: "Phil Bewig" <pbewig@gmail.com>
Cc: Matthew Flatt <mflatt@cs.utah.edu>, bugs@plt-scheme.org
Subject: Re: [plt-bug] all/8963: Space leak in infinite streams
Date: Mon, 24 Sep 2007 16:55:27 -0400
On Sep 24, Phil Bewig wrote:
> With 371, memory consumption (Total Commit Charge) is bouncing
> around in a 64MB range, with about half a minute between successive
> high points. I guess the garbage collector hits some limit at that
> point. I'll let you know if I have any other problems.
This is strange. I definitely see the problem using your original
example, and Matthew said that he sees it too.
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://www.barzilay.org/ Maze is Life!
From: "Jos Koot" <jos.koot@telefonica.net>
To: <bugs@plt-scheme.org>, "Phil Bewig" <pbewig@gmail.com>,
"Eli Barzilay" <eli@barzilay.org>,
"Matthew Flatt" <mflatt@cs.utah.edu>
Cc:
Subject: Re: all/8963: Space leak in infinite streams
Date: Tue, 25 Sep 2007 00:23:46 +0200
This is a multi-part message in MIME format.
------=_NextPart_000_0018_01C7FF0A.562F8860
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
See also problem 8883.
Jos Koot
((((lambda(x)((((((x x)x)x)x)x)x))
(lambda(x)(lambda(y)(x(x y)))))
(lambda(x)(write x)x))
'greeting)
------=_NextPart_000_0018_01C7FF0A.562F8860
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Diso-8859-1">
<META content=3D"MSHTML 6.00.6000.16525" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT face=3D"Courier New" size=3D2>See also problem =
8883.</FONT></DIV>
<DIV><FONT face=3D"Courier New" size=3D2>Jos Koot</FONT></DIV>
<DIV><FONT face=3D"Courier New" size=3D2><BR>((((lambda(x)((((((x=20
x)x)x)x)x)x))<BR> (lambda(x)(lambda(y)(x(x y)))))<BR> =20
(lambda(x)(write x)x))<BR> 'greeting)</FONT></DIV></BODY></HTML>
------=_NextPart_000_0018_01C7FF0A.562F8860--
From: Eli Barzilay <eli@barzilay.org>
To: "Jos Koot" <jos.koot@telefonica.net>
Cc: <bugs@plt-scheme.org>, "Phil Bewig" <pbewig@gmail.com>,
"Matthew Flatt" <mflatt@cs.utah.edu>
Subject: Re: all/8963: Space leak in infinite streams
Date: Mon, 24 Sep 2007 18:36:44 -0400
On Sep 25, Jos Koot wrote:
> See also problem 8883.
You probably mean 8881.
If it's the same problem, then I'll mark it as a duplicate of this
one, since this one is more manageable.
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://www.barzilay.org/ Maze is Life!
From: "Phil Bewig" <pbewig@gmail.com>
To: "Eli Barzilay" <eli@barzilay.org>
Cc: "Matthew Flatt" <mflatt@cs.utah.edu>, bugs@plt-scheme.org
Subject: Re: [plt-bug] all/8963: Space leak in infinite streams
Date: Mon, 24 Sep 2007 18:40:07 -0500
------=_Part_46404_18123249.1190677207570
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
My machine at home is 370. It exhibits the same behavior as 371 -- memory
starts at a low point, increases gradually to about 64MB greater than the
low point, then drops again to the low point. The cycle time is longer,
about five minutes, because my machine at home is slower (I didn't realize
how much slower).
On both machines, I noticed that the first time the growth occurred, it
stopped short of the maximum before recycling to the low point. I didn't
think to note it at work, but at home I noted that the first breakpoint was
about 32MB above the low point. I guess there are multiple levels of
garbage, and the first collection kicks in at a lower level than the second.
As Matthew points out, this is a bug. The memory growth should be zero,
because the promise is being mutated, so no memory needs to be allocated.
And Chez (the Petite interpreter, version 6.X, I forget exactly, maybe 6.9)
works properly, with zero memory growth, so I have some confidence in my
code.
Both home and work machines are Windows XP, if that means anything to you.
The work machine is patched up to date, the home machine isn't.
Phil
On 9/24/07, Eli Barzilay <eli@barzilay.org> wrote:
> On Sep 24, Phil Bewig wrote:
> > With 371, memory consumption (Total Commit Charge) is bouncing
> > around in a 64MB range, with about half a minute between successive
> > high points. I guess the garbage collector hits some limit at that
> > point. I'll let you know if I have any other problems.
>
> This is strange. I definitely see the problem using your original
> example, and Matthew said that he sees it too.
>
> --
> ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
> http://www.barzilay.org/ Maze is Life!
>
------=_Part_46404_18123249.1190677207570
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
<div>My machine at home is 370. It exhibits the same behavior as 371 -- memory starts at a low point, increases gradually to about 64MB greater than the low point, then drops again to the low point. The cycle time is longer, about five minutes, because my machine at home is slower (I didn't realize how much slower).
</div>
<div> </div>
<div>On both machines, I noticed that the first time the growth occurred, it stopped short of the maximum before recycling to the low point. I didn't think to note it at work, but at home I noted that the first breakpoint was about 32MB above the low point. I guess there are multiple levels of garbage, and the first collection kicks in at a lower level than the second.
</div>
<div> </div>
<div>As Matthew points out, this is a bug. The memory growth should be zero, because the promise is being mutated, so no memory needs to be allocated. And Chez (the Petite interpreter, version 6.X, I forget exactly, maybe
6.9) works properly, with zero memory growth, so I have some confidence in my code.</div>
<div> </div>
<div>Both home and work machines are Windows XP, if that means anything to you. The work machine is patched up to date, the home machine isn't.</div>
<div> </div>
<div>Phil</div>
<div><span class="gmail_quote"></span> </div>
<div><span class="gmail_quote">On 9/24/07, <b class="gmail_sendername">Eli Barzilay</b> <<a href="mailto:eli@barzilay.org">eli@barzilay.org</a>> wrote:</span></div>
<blockquote class="gmail_quote" style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: #ccc 1px solid">On Sep 24, Phil Bewig wrote:<br>> With 371, memory consumption (Total Commit Charge) is bouncing<br>> around in a 64MB range, with about half a minute between successive
<br>> high points. I guess the garbage collector hits some limit at that<br>> point. I'll let you know if I have any other problems.<br><br>This is strange. I definitely see the problem using your original<br>
example, and Matthew said that he sees it too.<br><br>--<br> ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:<br> <a href="http://www.barzilay.org/">http://www.barzilay.org/</a> Maze is Life!
<br></blockquote><br>
------=_Part_46404_18123249.1190677207570--
From: Eli Barzilay <eli@barzilay.org>
To: "Phil Bewig" <pbewig@gmail.com>
Cc: "Matthew Flatt" <mflatt@cs.utah.edu>, bugs@plt-scheme.org
Subject: Re: [plt-bug] all/8963: Space leak in infinite streams
Date: Mon, 24 Sep 2007 20:51:44 -0400
On Sep 24, Phil Bewig wrote:
> [...]
> On both machines, I noticed that the first time the growth occurred,
> it stopped short of the maximum before recycling to the low point.
> I didn't think to note it at work, but at home I noted that the
> first breakpoint was about 32MB above the low point. I guess there
> are multiple levels of garbage, and the first collection kicks in at
> a lower level than the second.
Yes, the 3m GC is generational. The strange thing is that you don't
see a problem now, where we do. ("No problem" since memory does get
reclaimed.)
> As Matthew points out, this is a bug. The memory growth should be
> zero, because the promise is being mutated, so no memory needs to be
> allocated. And Chez (the Petite interpreter, version 6.X, I forget
> exactly, maybe 6.9) works properly, with zero memory growth, so I
> have some confidence in my code.
I have talked to Matthew earlier, and we both have the same guess:
such things can blow up when the language implementation itself holds
on to some object. The likely cause of this is MzScheme holding a
reference to some value where Chez's compiler optimzes it away -- or
just computes things differently (eg, evaluating arguments in a
different order).
(In any case, this is in Matthew's world now...)
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://www.barzilay.org/ Maze is Life!
From: Eli Barzilay <eli@barzilay.org>
To: "Matthew Flatt" <mflatt@cs.utah.edu>
Cc: "Phil Bewig" <pbewig@gmail.com>, bugs@plt-scheme.org
Subject: Re: [plt-bug] all/8963: Space leak in infinite streams
Date: Mon, 24 Sep 2007 21:57:19 -0400
On Sep 24, Eli Barzilay wrote:
> [...]
Matthew -- I found a way to make it run in constant space, "it" being
my lazy scheme example of
(define (from n) (cons n (from (add1 n))))
(list-ref (filter zero? (from 0)) 1)
The change is something I should have tried before -- I changed my
definition of `filter' like this:
(define* (filter pred list)
(let ([pred (! pred)])
(let loop ([list (! list)])
(cond [(null? list) list]
[(pair? list)
(let ([x (car list)]
[xs (~ (loop (! (cdr (begin0 list (set! list #f))))))])
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^
(if (!*app pred x) (cons x xs) xs))]
[else (error 'filter "not a proper list: ~e" list)]))))
I'm not happy with this change, do you see why this is needed? (Given
that force will set! the promise closue away when it's done.) Is
there a better way to do this, or is there some missing mzscheme-level
optimization?
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://www.barzilay.org/ Maze is Life!
From: Matthew Flatt <mflatt@cs.utah.edu>
To: Eli Barzilay <eli@barzilay.org>
Cc: "Phil Bewig" <pbewig@gmail.com>, bugs@plt-scheme.org
Subject: Re: [plt-bug] all/8963: Space leak in infinite streams
Date: Mon, 24 Sep 2007 21:44:20 -0600
Quoting Eli Barzilay:
> The change is something I should have tried before -- I changed my
> definition of `filter' like this:
>
> (define* (filter pred list)
> (let ([pred (! pred)])
> (let loop ([list (! list)])
> (cond [(null? list) list]
> [(pair? list)
> (let ([x (car list)]
> [xs (~ (loop (! (cdr (begin0 list (set! list #f))))))])
> ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> (if (!*app pred x) (cons x xs) xs))]
> [else (error 'filter "not a proper list: ~e" list)]))))
>
> I'm not happy with this change, do you see why this is needed?
Yes --- it's exactly the sort of thing that I was going to look for.
The problem is that the `list' binding stays live until the `filter'
procedure either returns or tail-calls, even though the continuation of
the `cdr' call doesn't need it. That's the way in which MzScheme isn't
"safe for space".
I have occasionally considered fixing this, but it's never caused
enough trouble before (as far as I know) to get my attention. I'll move
it up on the list.
Matthew
From: "Phil Bewig" <pbewig@gmail.com>
To: "Matthew Flatt" <mflatt@cs.utah.edu>
Cc: "Eli Barzilay" <eli@barzilay.org>, bugs@plt-scheme.org
Subject: Re: [plt-bug] all/8963: Space leak in infinite streams
Date: Tue, 25 Sep 2007 07:32:59 -0500
------=_Part_1032_23629203.1190723579447
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
Thanks. Sometimes these infinite streams make my head spin, and I'm not
sure what I'm doing wrong -- or even if I can tell the difference between
right and wrong. I'll look forward to the correction.
I've finished coding on my stream SRFI, but still have some writing to do.
I expect to submit it in about a month. Since the times3 bug was notorious
in the discussion list of SRFI-40, I'll mention it again in the new SRFI,
which means that a lot of people may all be running into this bug in about a
month.
On 9/24/07, Matthew Flatt <mflatt@cs.utah.edu> wrote:
>
> Quoting Eli Barzilay:
> > The change is something I should have tried before -- I changed my
> > definition of `filter' like this:
> >
> > (define* (filter pred list)
> > (let ([pred (! pred)])
> > (let loop ([list (! list)])
> > (cond [(null? list) list]
> > [(pair? list)
> > (let ([x (car list)]
> > [xs (~ (loop (! (cdr (begin0 list (set! list
> #f))))))])
> > ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > (if (!*app pred x) (cons x xs) xs))]
> > [else (error 'filter "not a proper list: ~e" list)]))))
> >
> > I'm not happy with this change, do you see why this is needed?
>
> Yes --- it's exactly the sort of thing that I was going to look for.
>
> The problem is that the `list' binding stays live until the `filter'
> procedure either returns or tail-calls, even though the continuation of
> the `cdr' call doesn't need it. That's the way in which MzScheme isn't
> "safe for space".
>
> I have occasionally considered fixing this, but it's never caused
> enough trouble before (as far as I know) to get my attention. I'll move
> it up on the list.
>
> Matthew
>
>
------=_Part_1032_23629203.1190723579447
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
Thanks. Sometimes these infinite streams make my head spin, and I'm not sure what I'm doing wrong -- or even if I can tell the difference between right and wrong. I'll look forward to the correction.<br><br>I've finished coding on my stream SRFI, but still have some writing to do. I expect to submit it in about a month. Since the times3 bug was notorious in the discussion list of SRFI-40, I'll mention it again in the new SRFI, which means that a lot of people may all be running into this bug in about a month.
<br><br><div><span class="gmail_quote">On 9/24/07, <b class="gmail_sendername">Matthew Flatt</b> <<a href="mailto:mflatt@cs.utah.edu">mflatt@cs.utah.edu</a>> wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Quoting Eli Barzilay:<br>> The change is something I should have tried before -- I changed my<br>> definition of `filter' like this:<br>><br>> (define* (filter pred list)<br>> (let ([pred (! pred)])
<br>> (let loop ([list (! list)])<br>> (cond [(null? list) list]<br>> [(pair? list)<br>> (let ([x (car list)]<br>> [xs (~ (loop (! (cdr (begin0 list (set! list #f))))))])
<br>> ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^<br>> (if (!*app pred x) (cons x xs) xs))]<br>> [else (error 'filter "not a proper list: ~e" list)]))))
<br>><br>> I'm not happy with this change, do you see why this is needed?<br><br>Yes --- it's exactly the sort of thing that I was going to look for.<br><br>The problem is that the `list' binding stays live until the `filter'
<br>procedure either returns or tail-calls, even though the continuation of<br>the `cdr' call doesn't need it. That's the way in which MzScheme isn't<br>"safe for space".<br><br>I have occasionally considered fixing this, but it's never caused
<br>enough trouble before (as far as I know) to get my attention. I'll move<br>it up on the list.<br><br>Matthew<br><br></blockquote></div><br>
------=_Part_1032_23629203.1190723579447--
State changed from "open" to "closed" by mflatt at Sat, 09 Feb 2008 15:24:34 -0500
Reason>>> Fixed in v3.99.0.11