andreikop / qutepart

Code editor component for PyQt5
http://enki-editor.org
GNU Lesser General Public License v2.1
111 stars 30 forks source link

Memory leaks in cParser #83

Open andreikop opened 4 years ago

andreikop commented 4 years ago

@SergeySatskiy , I hope you don't mind if I publish the mail here.

(Russinan)

Для анализа я инструментировал код с помощью guppy. Идея была простая:
- инициализация
- установка reference point для кучи, доступ к которой предоставляет guppy
- выполнение одного и того же действия несколько раз (здесь я привожу данные для открытия вкладки с пустым питон файлом и ее закрытие 5 раз)
- запуск отладчика и просмотр кучи

guppy предоставляет вызов heapu() - далее в переменной unreachable - где скорее всего оседают не освобожденные данные от модулей расширения, написанных на C.
В моем эксперименте данные копились в процессе работы, поэтому я сделал два эксперимента: один с C парсером синтаксиса, а второй с питон парсером из пакета qutepart. Для включения питон парсера потребовалось прямое изменение в loader.py, благо код в виртуальном окружении.

Результат запуска с C парсером:

(Pdb) p unreachable
Data from unreachable objects relative to: Fri Feb 14 10:33:19 2020.
Summary of difference operation (A-B).
        Count     Size
  A      2616   388639
  B      1817   287452
  A-B     799   101187  =      35.2 % of B

Differences by kind, largest absolute size diffs first.
 Index  Count     Size  Cumulative  % of B Type
     0     20    41760     41760      14.5 qutepart.syntax.cParser.keyword
     1    371    21475     63235        22 str
     2    158    17696     80931      28.2 PyQt5.QtGui.QTextCharFormat
     3     80    10744     91675      31.9 list
     4     37     2960     94635      32.9 qutepart.syntax.cParser.RegExpr
     5     45     1800     96435      33.5 qutepart.syntax.cParser.IncludeRules
     6     23     1104     97539      33.9 qutepart.syntax.cParser.DetectChar
     7      3      976     98515      34.3 dict
     8     17      816     99331      34.6 qutepart.syntax.cParser.StringDetect
     9      7      560     99891      34.8 builtins.weakref

Здесь видно, что есть порядком данных в unreachable части.

Результат запуска с питон парсером:  

(Pdb) p unreachable
Data from unreachable objects relative to: Fri Feb 14 10:31:45 2020.
Summary of difference operation (A-B).
        Count     Size
  A      1854   290452
  B      1821   287756
  A-B      33     2696  =     0.937 % of B

Differences by kind, largest absolute size diffs first.
 Index  Count     Size  Cumulative  % of B Type
     0     30     2432      2432     0.845 list
     1      5      400      2832     0.984 builtins.weakref
     2     -1      -80      2752     0.956 builtins.dict_keyiterator
     3     -1      -56      2696     0.937 builtins.list_iterator

Здесь гораздо лучше!
Выглядит так, как если в C парсере есть утечки памяти.

there are also andreikop/enki#436 by @vi, which might be related

SergeySatskiy commented 4 years ago

Sure, I don't mind