Re: [vim/vim] fix: ":for" over a tuple leaks memory on every iteration (PR #20914)
Samuel Schlesinger (Vim Github Repository) <[email protected]> Sun, 02 Aug 2026 04:24:09 -0700
| Newsgroups | gmane.editors.vim.devel |
|---|---|
| Message-ID | <vim/vim/pull/20914/[email protected]> |
----==_mimepart_6a6f28d9c3d7_f3116057496f8
Content-Type: text/plain; charset="UTF-8"
SamuelSchlesinger left a comment (vim/vim#20914)
```vimscript
" Demonstrates the ":for" over a tuple memory leak.
" Run with: vim -N -u NONE -i NONE -es -S tuple_leak_demo.vim
"
" Each round runs 100,000 iterations of a ":for" loop over a two-string
" tuple and then prints the process RSS. On an unpatched Vim the RSS grows
" by ~26 MB every round (the copied tuple items are never freed). On a
" patched Vim the RSS is flat after the first round's allocator warm-up.
func s:Rss()
return str2nr(system('ps -o rss= -p ' . getpid()))
endfunc
func s:Print(msg)
call writefile([a:msg], '/dev/stdout', 'a')
endfunc
let s:str = repeat('abcdefghij', 20)
call s:Rss() " warm up the ps invocation itself
call s:Print('start: RSS ' . s:Rss() . ' KB')
for s:round in range(1, 5)
for s:i in range(100000)
for s:x in (s:str, 'short')
endfor
endfor
call s:Print('after round ' . s:round . ': RSS ' . s:Rss() . ' KB')
endfor
qa!
```
--
Reply to this email directly or view it on GitHub:
https://github.com/vim/vim/pull/20914#issuecomment-5157497193
You are receiving this because you are subscribed to this thread.
Message ID: <vim/vim/pull/20914/[email protected]>
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups "vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To view this discussion visit https://groups.google.com/d/msgid/vim_dev/vim/vim/pull/20914/c5157497193%40github.com.
----==_mimepart_6a6f28d9c3d7_f3116057496f8
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div style=3D"display: flex; flex-wrap: wrap; white-space: pre-wrap; align-=
items: center; "><img height=3D"20" width=3D"20" style=3D"border-radius:50%=
; margin-right: 4px;" decoding=3D"async" src=3D"https://avatars.githubuserc=
ontent.com/u/10200200" /><strong>SamuelSchlesinger</strong> left a comment =
<a href=3D"https://github.com/vim/vim/pull/20914#issuecomment-5157497193">(=
vim/vim#20914)</a></div>
<div class=3D"highlight highlight-source-viml" dir=3D"auto"><pre class=3D"n=
otranslate"><span class=3D"pl-c"><span class=3D"pl-c">"</span> Demonstrates=
the ":for" over a tuple memory leak.</span>
<span class=3D"pl-c"><span class=3D"pl-c">"</span> Run with: vim -N -u NON=
E -i NONE -es -S tuple_leak_demo.vim</span>
<span class=3D"pl-c"><span class=3D"pl-c">"</span></span>
<span class=3D"pl-c"><span class=3D"pl-c">"</span> Each round runs 100,000 =
iterations of a ":for" loop over a two-string</span>
<span class=3D"pl-c"><span class=3D"pl-c">"</span> tuple and then prints th=
e process RSS. On an unpatched Vim the RSS grows</span>
<span class=3D"pl-c"><span class=3D"pl-c">"</span> by ~26 MB every round (t=
he copied tuple items are never freed). On a</span>
<span class=3D"pl-c"><span class=3D"pl-c">"</span> patched Vim the RSS is f=
lat after the first round's allocator warm-up.</span>
<span class=3D"pl-k">func</span> <span class=3D"pl-en"><span class=3D"pl-k"=
>s:</span>Rss</span>()
<span class=3D"pl-k">return</span> <span class=3D"pl-en">str2nr</span>(<s=
pan class=3D"pl-en">system</span>(<span class=3D"pl-s"><span class=3D"pl-pd=
s">'</span>ps -o rss=3D -p <span class=3D"pl-pds">'</span></span> . <span c=
lass=3D"pl-en">getpid</span>()))
<span class=3D"pl-k">endfunc</span>
<span class=3D"pl-k">func</span> <span class=3D"pl-en"><span class=3D"pl-k"=
>s:</span>Print</span>(msg)
<span class=3D"pl-c1">call</span> <span class=3D"pl-en">writefile</span>(=
[<span class=3D"pl-smi"><span class=3D"pl-k">a:</span>msg</span>], <span cl=
ass=3D"pl-s"><span class=3D"pl-pds">'</span>/dev/stdout<span class=3D"pl-pd=
s">'</span></span>, <span class=3D"pl-s"><span class=3D"pl-pds">'</span>a<s=
pan class=3D"pl-pds">'</span></span>)
<span class=3D"pl-k">endfunc</span>
<span class=3D"pl-k">let</span> <span class=3D"pl-smi"><span class=3D"pl-k"=
>s:</span>str</span> <span class=3D"pl-k">=3D</span> <span class=3D"pl-en">=
repeat</span>(<span class=3D"pl-s"><span class=3D"pl-pds">'</span>abcdefghi=
j<span class=3D"pl-pds">'</span></span>, <span class=3D"pl-c1">20</span>)
<span class=3D"pl-c1">call</span> <span class=3D"pl-en"><span class=3D"pl-k=
">s:</span>Rss</span>()<span class=3D"pl-c"> <span class=3D"pl-c">"</spa=
n> warm up the ps invocation itself</span>
<span class=3D"pl-c1">call</span> <span class=3D"pl-en"><span class=3D"pl-k=
">s:</span>Print</span>(<span class=3D"pl-s"><span class=3D"pl-pds">'</span=
>start: RSS <span class=3D"pl-pds">'</span></span> . <span class=3D=
"pl-en"><span class=3D"pl-k">s:</span>Rss</span>() . <span class=3D"pl-s"><=
span class=3D"pl-pds">'</span> KB<span class=3D"pl-pds">'</span></span>)
<span class=3D"pl-k">for</span> <span class=3D"pl-smi"><span class=3D"pl-k"=
>s:</span>round</span> <span class=3D"pl-k">in</span> <span class=3D"pl-en"=
>range</span>(<span class=3D"pl-c1">1</span>, <span class=3D"pl-c1">5</span=
>)
<span class=3D"pl-k">for</span> <span class=3D"pl-smi"><span class=3D"pl-=
k">s:</span>i</span> <span class=3D"pl-k">in</span> <span class=3D"pl-en">r=
ange</span>(<span class=3D"pl-c1">100000</span>)
<span class=3D"pl-k">for</span> <span class=3D"pl-smi"><span class=3D"p=
l-k">s:</span>x</span> <span class=3D"pl-k">in</span> (<span class=3D"pl-sm=
i"><span class=3D"pl-k">s:</span>str</span>, <span class=3D"pl-s"><span cla=
ss=3D"pl-pds">'</span>short<span class=3D"pl-pds">'</span></span>)
<span class=3D"pl-k">endfor</span>
<span class=3D"pl-k">endfor</span>
<span class=3D"pl-c1">call</span> <span class=3D"pl-en"><span class=3D"pl=
-k">s:</span>Print</span>(<span class=3D"pl-s"><span class=3D"pl-pds">'</sp=
an>after round <span class=3D"pl-pds">'</span></span> . <span class=3D"pl-s=
mi"><span class=3D"pl-k">s:</span>round</span> . <span class=3D"pl-s"><span=
class=3D"pl-pds">'</span>: RSS <span class=3D"pl-pds">'</span></span> . <s=
pan class=3D"pl-en"><span class=3D"pl-k">s:</span>Rss</span>() . <span clas=
s=3D"pl-s"><span class=3D"pl-pds">'</span> KB<span class=3D"pl-pds">'</span=
></span>)
<span class=3D"pl-k">endfor</span>
<span class=3D"pl-c1">qa</span><span class=3D"pl-k">!</span></pre></div>
<p style=3D"font-size:small;-webkit-text-size-adjust:none;color:#666;">&mda=
sh;<br />Reply to this email directly, <a href=3D"https://github.com/vim/vi=
m/pull/20914#issuecomment-5157497193">view it on GitHub</a>, or <a href=3D"=
https://github.com/notifications/unsubscribe-auth/ACY5DGCK55JULZWHRIHEIDD5H=
4QFTAVCNFSNUABEKJSXA33TNF2G64TZHM2DAOJZG42DQMR3JFZXG5LFHM2TAMZYG4YDANRVGSQX=
MAQ">unsubscribe</a>.<br />Triage notifications, keep track of coding agent=
tasks and review pull requests on the go with GitHub Mobile for <a href=3D=
"https://github.com/notifications/mobile/ios/ACY5DGE24IGN5H2ATFOXHAL5H4QFTA=
5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKMJVG42DSNZRHEZ2M4TFM=
FZW63VKON2WE43DOJUWEZLEUVSXMZLOOSVGM33PORSXEX3JN5ZQ">iOS</a> and <a href=3D=
"https://github.com/notifications/mobile/android/ACY5DGGU6GQEEV2UVG5WOZD5H4=
QFTA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKMJVG42DSNZRHEZ2M=
4TFMFZW63VKON2WE43DOJUWEZLEUVSXMZLOOSXGM33PORSXEX3BNZSHE33JMQ">Android</a>.=
Download it today!
<br />You are receiving this because you are subscribed to this thread.<img=
src=3D"https://github.com/notifications/beacon/ACY5DGGN7PUORWZ3VQAQPWD5H4Q=
FTBFCNFSM6AAAAAC4V66BCKWGG33NNVSW45C7OR4XAZNMJFZXG5LFINXW23LFNZ2KUY3PNVWWK3=
TUL5UWJTYAAAAACM3JFFU2M4TFMFZW63VKON2WE43DOJUWEZLE.gif" height=3D"1" width=
=3D"1" alt=3D"" /><span style=3D"color: transparent; font-size: 0; display:=
none; visibility: hidden; overflow: hidden; opacity: 0; width: 0; height: =
0; max-width: 0; max-height: 0; mso-hide: all">Message ID: <span><vim/vi=
m/pull/20914/c5157497193</span><span>@</span><span>github</span><span>.</sp=
an><span>com></span></span></p>
<script type=3D"application/ld+json">[
{
"@context": "http://schema.org",
"@type": "EmailMessage",
"potentialAction": {
"@type": "ViewAction",
"target": "https://github.com/vim/vim/pull/20914#issuecomment-5157497193",
"url": "https://github.com/vim/vim/pull/20914#issuecomment-5157497193",
"name": "View Pull Request"
},
"description": "View this Pull Request on GitHub",
"publisher": {
"@type": "Organization",
"name": "GitHub",
"url": "https://github.com"
}
}
]</script>
<p></p>
-- <br />
-- <br />
You received this message from the "vim_dev" maillist.<br />
Do not top-post! Type your reply below the text you are replying to.<br />
For more information, visit <a href=3D"http://www.vim.org/maillist.php">htt=
p://www.vim.org/maillist.php</a><br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;vim_dev" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:[email protected]">vim_dev+uns=
[email protected]</a>.<br />
To view this discussion visit <a href=3D"https://groups.google.com/d/msgid/=
vim_dev/vim/vim/pull/20914/c5157497193%40github.com?utm_medium=3Demail&utm_=
source=3Dfooter">https://groups.google.com/d/msgid/vim_dev/vim/vim/pull/209=
14/c5157497193%40github.com</a>.<br />
----==_mimepart_6a6f28d9c3d7_f3116057496f8--