Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

`loop { 0, .1 ... 1000 }` leaks memory #4592

Closed
p6rt opened this issue Sep 25, 2015 · 5 comments
Closed

`loop { 0, .1 ... 1000 }` leaks memory #4592

p6rt opened this issue Sep 25, 2015 · 5 comments
Labels

Comments

@p6rt
Copy link

@p6rt p6rt commented Sep 25, 2015

Migrated from rt.perl.org#126189 (status was 'open')

Searchable as RT126189$

@p6rt
Copy link
Author

@p6rt p6rt commented Sep 25, 2015

From @TimToady

Leaks memory, probably due to the implicit function being called to produce
the next value. Also leaks with an explicit function, or any other form of
loop around it. (We know the sequence is terminating even if Rats aren't
exact, because the implicit form turns the match into an inequality. In
any case, one can sum the series and print it out each iteration to be
sure.)

@p6rt
Copy link
Author

@p6rt p6rt commented Nov 14, 2015

From @FROGGS

I did run this​:

$ valgrind --leak-check=full --show-leak-kinds=all /home/froggs/dev/nqp/install/bin/moar --execname="$0" --libpath="/home/froggs/dev/nqp/install/share/nqp/lib" --libpath="/home/froggs/dev/nqp/install/share/perl6/lib" --libpath="/home/froggs/dev/nqp/install/share/perl6/runtime" --full-cleanup /home/froggs/dev/nqp/install/share/perl6/runtime/perl6.moarvm -e 'my $x = 0; loop { 0, .1 ... 1000; exit if $x++ > 10; }'

And the two biggets memory consumoptions are​:

==8073== 5,750,160 bytes in 239,590 blocks are still reachable in loss record 2,318 of 2,319
==8073== at 0x4C2AB80​: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8073== by 0x50396A6​: MVM_malloc (alloc.h​:2)
==8073== by 0x50396A6​: MVM_bigint_div (bigintops.c​:550)
==8073== by 0x4F95053​: MVM_interp_run (interp.c​:1717)
==8073== by 0x503F5CD​: MVM_vm_run_file (moar.c​:249)
==8073== by 0x401036​: main (main.c​:191)
==8073==
==8073== 122,670,080 bytes in 239,590 blocks are still reachable in loss record 2,319 of 2,319
==8073== at 0x4C2AB80​: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8073== by 0x50497F9​: mp_init_size (bn_mp_init_size.c​:27)
==8073== by 0x5048345​: mp_div (bn_mp_div.c​:126)
==8073== by 0x50396DE​: MVM_bigint_div (bigintops.c​:574)
==8073== by 0x4F95053​: MVM_interp_run (interp.c​:1717)
==8073== by 0x503F5CD​: MVM_vm_run_file (moar.c​:249)
==8073== by 0x401036​: main (main.c​:191)

Note that there are still reachable. All non-reachable areas are just a bunch of kilobytes in size.

@p6rt
Copy link
Author

@p6rt p6rt commented Nov 14, 2015

The RT System itself - Status changed from 'new' to 'open'

@p6rt
Copy link
Author

@p6rt p6rt commented Jan 17, 2017

From @smls

Still present on Rakudo version 2016.12-315-gdaf7e5185 built on MoarVM version 2016.12-113-gd1da1bac.

Though to avoid a warning, you now have to write it like this​:

  loop { sink (0, .1 ... 1000) }

Also, while the memory leak that remains *after* each application of `...` may be the bigger worry, I think it shouldn't even accumulate memory *during* each iteration of `...`.

Compare​:

1) The following program uses 39.7 M of RAM shortly after starting, and still 39.7 M one minute later​:

  .sink for 1..*

2) Whereas the following program uses about 52.4 M shortly after starting, and then keeps steadily accumulating RAM usage for as long as you run it (about 137.1 M after one minute)​:

  .sink for 1...*

(Same problem for `1, 3 ... *` or `1, *+1 ... *` etc.)

Brad Gilbert on Stack Overflow <http://stackoverflow.com/a/41670048/1160124> suggested that `LIST, CODE ... END` caches the whole sequence internally, in case CODE reference it.
But couldn't it simply look at the arity/count of CODE to know how many elements it needs to keep in memory?

@p6rt p6rt added the perf label Jan 5, 2020
@AlexDaniel
Copy link
Member

@AlexDaniel AlexDaniel commented Feb 8, 2020

I'm pretty sure that this is now resolved. I had it running for like an hour or so, and maxrss stabilized on 148916 KiB. That's of course very high, but it's what any script will reach, the code in question is not leaking any extra memory.

I tried both this:

perl6 -e 'loop { say 0, .1 ... 1000; use Telemetry; say T<max-rss> }'

And this:

perl6 -e 'loop { 0, .1 ... 1000; use Telemetry; say T<max-rss> }'
@AlexDaniel AlexDaniel closed this Feb 8, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.