nixprime / cpsm

A CtrlP matcher, specialized for paths.
Apache License 2.0
202 stars 19 forks source link

Memory leak #51

Open nkouevda opened 5 years ago

nkouevda commented 5 years ago

Since 1cbd73cf144691482a2eb06d1e7f366618d9adfd, cpsm causes a memory leak in vim, most evident in large repos like linux where there are many results. Normally I see vim use 50-100 MB, but after a couple dozen ctrlp searches, this balloons to >500 MB, and continues to increase with each search. In even larger repos, it's trivial to hit >10 GB very quickly. Vim and python versions don't seem to make a difference, but for completeness, this is under vim 8.1.1300 and python 3.7.3.

Initially I suspected this was due to switching from py3 to py3eval, but I'm pretty sure that's irrelevant (tested both with and without vim/vim@8e9a24a127c4ef8833fdc3986623f96c7d04210f, and with reverting back to py3).

I've narrowed the issue down to the introduction of **_vim_eval("s:input"), specifically the "a:items" part. In fact, the following (applied to current master) almost entirely fixes the issue:

diff --git autoload/cpsm.py autoload/cpsm.py
index d864e8b..b65bd23 100644
--- autoload/cpsm.py
+++ autoload/cpsm.py
@@ -58,7 +58,7 @@ def ctrlp_match_with(**kwargs):
         return ["ERROR:" + ex_str], []

 def _ctrlp_match_evalinput():
-    return ctrlp_match_with(**_vim_eval("s:input"))
+    return ctrlp_match_with(items=_vim_eval("a:items"), **_vim_eval("s:input"))

 def ctrlp_match():
     """
diff --git autoload/cpsm.vim autoload/cpsm.vim
index 191935c..0cf4aa5 100644
--- autoload/cpsm.vim
+++ autoload/cpsm.vim
@@ -85,7 +85,6 @@ function cpsm#CtrlPMatch(items, str, limit, mmode, ispath, crfile, regex)
       let s:regex_line_prefix = g:ctrlp_line_prefix
     endif
     let s:input = {
-    \   'items': a:items,
     \   'query': a:str,
     \   'limit': a:limit,
     \   'mmode': a:mmode,

"Almost entirely" because memory still seems to leak (due to the rest of s:input?), but at a much slower rate. A more proper fix is completely reverting **_vim_eval("s:input") to the explicit list of kwargs, each _vim_eval'd separately, i.e. exactly what ctrlp_match() still does. That's what I've been doing to work around this issue: nkouevda/cpsm@e037128f4f5ed75cb7998db86d68b6a54937d752.

Either way I don't understand what the underlying issue is, which I suspect is in vim itself(?).