Доброго времени суток.
Сегодня совершенно случайно заметил, что okular жрет 16 гигов оперативки, в этот момент была открыта pdf'ка на 40 мегабайт. Стало интересно, захотелось понять причину. Протестировал его на нескольких pdf/djvu разных размеров. Проблема проявлялась во всех случаях. В результате было замечено, что аппетит у очкарика зависит от размера файла, т.е. на небольших экземплярах (2 - 5 мб) кушает в пределах 2 - 3 гб оперативки, на солидных книжищах (~1000 страниц, ~50 мб) сжирает в пределах 15 - 20 гб оперативки.
Не могу сказать, когда это началось, так как внешне на стабильность системы это никак не влияло. Машинка у меня на вырост, 32 кг памяти, а своп хоть и включен, но ни разу не было ситуации (не замечал этого), когда бы он использовался, поэтому и тормозов не было замечено.
Пришла в голову мысль поставить valgrind и посмотреть, что он скажет. Не знаю точно, что нужно делать, так как раньше не доводилось его не юзать, да и вообще нет опыта работы с профайлерами. Просматривая маны, бросилось в глаза два модуля, memcheck и massif. Вот результаты:
valgrind --leak-check=full okular
После запуска okular'а, был открыт pdf файл на 4 мб.
Выхлоп - http://pastebin.com/raw.php?i=20m3TQ2E
Взято из top:
2542776 1,998g 52848 S 0,0 6,4 0:06.62 okular
Далее был запущен massif и открыт тот же файл на 4 мб:
valgrind --tool=massif okular
ms_print massif.out.2478
Верхушка лога:
--------------------------------------------------------------------------------
Command: okular
Massif arguments: (none)
ms_print arguments: massif.out.2478
--------------------------------------------------------------------------------
GB
1.919^ #
| @@#
| @@:@@@#
| @@@@@:@@@#
| ::@:@ @@@:@@@#
| ::@: @:@ @@@:@@@#
| @@@::::@: @:@ @@@:@@@#
| ::@@ @: ::@: @:@ @@@:@@@#
| ::@::@@ @: ::@: @:@ @@@:@@@#
| @::: @::@@ @: ::@: @:@ @@@:@@@#
| :@::@::: @::@@ @: ::@: @:@ @@@:@@@#
| ::@:::@: @::: @::@@ @: ::@: @:@ @@@:@@@#
| @:: @: :@: @::: @::@@ @: ::@: @:@ @@@:@@@#
| ::::@:: @: :@: @::: @::@@ @: ::@: @:@ @@@:@@@#
| @@::::: @:: @: :@: @::: @::@@ @: ::@: @:@ @@@:@@@#
| ::@:@ : ::: @:: @: :@: @::: @::@@ @: ::@: @:@ @@@:@@@#
| :: @:@ : ::: @:: @: :@: @::: @::@@ @: ::@: @:@ @@@:@@@#
| ::::::: @:@ : ::: @:: @: :@: @::: @::@@ @: ::@: @:@ @@@:@@@#
| @:::: :: :: @:@ : ::: @:: @: :@: @::: @::@@ @: ::@: @:@ @@@:@@@#
| ::@@@:: : :: :: @:@ : ::: @:: @: :@: @::: @::@@ @: ::@: @:@ @@@:@@@#
0 +----------------------------------------------------------------------->Gi
0 42.85
Обжористый стек вызовов (взято из начала лога), тут он кушает всего 150 метров:
99.31% (156,626,353B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
->95.06% (149,931,100B) 0x6A4D60A: QImageData::create(QSize const&, QImage::Format, int) (in /usr/lib64/qt4/libQtGui.so.4.8.6)
| ->94.80% (149,517,876B) 0x6A4D75B: QImage::QImage(int, int, QImage::Format) (in /usr/lib64/qt4/libQtGui.so.4.8.6)
| | ->94.26% (148,661,288B) 0x6A4E9A1: QImage::copy(QRect const&) const (in /usr/lib64/qt4/libQtGui.so.4.8.6)
| | | ->78.71% (124,136,496B) 0x6A4F913: QImage::detach() (in /usr/lib64/qt4/libQtGui.so.4.8.6)
| | | | ->78.71% (124,136,496B) 0x6A750C5: QRasterPixmapData::createPixmapForImage(QImage&, QFlags<Qt::ImageConversionFlag>, bool) (in /usr/lib64/qt4/libQtGui.so.4.8.6)
| | | | | ->78.71% (124,136,496B) 0x6A75130: QRasterPixmapData::fromImage(QImage const&, QFlags<Qt::ImageConversionFlag>) (in /usr/lib64/qt4/libQtGui.so.4.8.6)
| | | | | ->78.71% (124,136,496B) 0x6A66ED0: QPixmap::fromImage(QImage const&, QFlags<Qt::ImageConversionFlag>) (in /usr/lib64/qt4/libQtGui.so.4.8.6)
| | | | | ->78.71% (124,136,496B) 0x182BD157: ??? (in /usr/lib64/libokularcore.so.5.0.0)
| | | | | ->78.71% (124,136,496B) 0x64828BC: QObject::event(QEvent*) (in /usr/lib64/qt4/libQtCore.so.4.8.6)
| | | | | ->78.71% (124,136,496B) 0x699935A: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /usr/lib64/qt4/libQtGui.so.4.8.6)
| | | | | ->78.71% (124,136,496B) 0x699FACB: QApplication::notify(QObject*, QEvent*) (in /usr/lib64/qt4/libQtGui.so.4.8.6)
| | | | | ->78.71% (124,136,496B) 0x5771568: KApplication::notify(QObject*, QEvent*) (in /usr/lib64/libkdeui.so.5.14.8)
| | | | | ->78.71% (124,136,496B) 0x646A26B: QCoreApplication::notifyInternal(QObject*, QEvent*) (in /usr/lib64/qt4/libQtCore.so.4.8.6)
| | | | | ->78.71% (124,136,496B) 0x646D488: QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (in /usr/lib64/qt4/libQtCore.so.4.8.6)
| | | | | ->78.71% (124,136,496B) 0x649818C: ??? (in /usr/lib64/qt4/libQtCore.so.4.8.6)
| | | | | ->78.71% (124,136,496B) 0xB2FC552: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.4200.2)
| | | | | ->78.71% (124,136,496B) 0xB2FC796: ??? (in /usr/lib64/libglib-2.0.so.0.4200.2)
| | | | | ->78.71% (124,136,496B) 0xB2FC83A: g_main_context_iteration (in /usr/lib64/libglib-2.0.so.0.4200.2)
| | | | | ->78.71% (124,136,496B) 0x649795C: QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (in /usr/lib64/qt4/libQtCore.so.4.8.6)
| | | | | ->78.71% (124,136,496B) 0x6A37674: ??? (in /usr/lib64/qt4/libQtGui.so.4.8.6)
| | | | | ->78.71% (124,136,496B) 0x6468DFD: QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (in /usr/lib64/qt4/libQtCore.so.4.8.6)
| | | | | ->78.71% (124,136,496B) 0x64690F3: QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (in /usr/lib64/qt4/libQtCore.so.4.8.6)
| | | | | ->78.71% (124,136,496B) 0x646E557: QCoreApplication::exec() (in /usr/lib64/qt4/libQtCore.so.4.8.6)
| | | | | ->78.71% (124,136,496B) 0x409BDE: ??? (in /usr/bin/okular)
| | | | | ->78.71% (124,136,496B) 0x7788AA3: (below main) (in /lib64/libc-2.20.so)
Этот же стек (в конце лога), но теперь он кушает 2 гигабайта:
--------------------------------------------------------------------------------
n time(i) total(B) useful-heap(B) extra-heap(B) stacks(B)
--------------------------------------------------------------------------------
56 46,009,662,363 2,060,416,776 2,057,966,717 2,450,059 0
99.88% (2,057,966,717B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
->97.66% (2,012,172,328B) 0x6A4D60A: QImageData::create(QSize const&, QImage::Format, int) (in /usr/lib64/qt4/libQtGui.so.4.8.6)
| ->97.65% (2,011,902,528B) 0x6A4D75B: QImage::QImage(int, int, QImage::Format) (in /usr/lib64/qt4/libQtGui.so.4.8.6)
| | ->97.62% (2,011,368,392B) 0x6A4E9A1: QImage::copy(QRect const&) const (in /usr/lib64/qt4/libQtGui.so.4.8.6)
| | | ->96.43% (1,986,843,600B) 0x6A4F913: QImage::detach() (in /usr/lib64/qt4/libQtGui.so.4.8.6)
| | | | ->96.43% (1,986,843,600B) 0x6A750C5: QRasterPixmapData::createPixmapForImage(QImage&, QFlags<Qt::ImageConversionFlag>, bool) (in /usr/lib64/qt4/libQtGui.so.4.8.6)
| | | | | ->96.43% (1,986,843,600B) 0x6A75130: QRasterPixmapData::fromImage(QImage const&, QFlags<Qt::ImageConversionFlag>) (in /usr/lib64/qt4/libQtGui.so.4.8.6)
| | | | | ->96.43% (1,986,843,600B) 0x6A66ED0: QPixmap::fromImage(QImage const&, QFlags<Qt::ImageConversionFlag>) (in /usr/lib64/qt4/libQtGui.so.4.8.6)
| | | | | ->96.43% (1,986,843,600B) 0x182BD157: ??? (in /usr/lib64/libokularcore.so.5.0.0)
| | | | | ->96.43% (1,986,843,600B) 0x64828BC: QObject::event(QEvent*) (in /usr/lib64/qt4/libQtCore.so.4.8.6)
| | | | | ->96.43% (1,986,843,600B) 0x699935A: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /usr/lib64/qt4/libQtGui.so.4.8.6)
| | | | | ->96.43% (1,986,843,600B) 0x699FACB: QApplication::notify(QObject*, QEvent*) (in /usr/lib64/qt4/libQtGui.so.4.8.6)
| | | | | ->96.43% (1,986,843,600B) 0x5771568: KApplication::notify(QObject*, QEvent*) (in /usr/lib64/libkdeui.so.5.14.8)
| | | | | ->96.43% (1,986,843,600B) 0x646A26B: QCoreApplication::notifyInternal(QObject*, QEvent*) (in /usr/lib64/qt4/libQtCore.so.4.8.6)
| | | | | ->96.43% (1,986,843,600B) 0x646D488: QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (in /usr/lib64/qt4/libQtCore.so.4.8.6)
| | | | | ->96.43% (1,986,843,600B) 0x649818C: ??? (in /usr/lib64/qt4/libQtCore.so.4.8.6)
| | | | | ->96.43% (1,986,843,600B) 0xB2FC552: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.4200.2)
| | | | | ->96.43% (1,986,843,600B) 0xB2FC796: ??? (in /usr/lib64/libglib-2.0.so.0.4200.2)
| | | | | ->96.43% (1,986,843,600B) 0xB2FC83A: g_main_context_iteration (in /usr/lib64/libglib-2.0.so.0.4200.2)
| | | | | ->96.43% (1,986,843,600B) 0x649795C: QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (in /usr/lib64/qt4/libQtCore.so.4.8.6)
| | | | | ->96.43% (1,986,843,600B) 0x6A37674: ??? (in /usr/lib64/qt4/libQtGui.so.4.8.6)
| | | | | ->96.43% (1,986,843,600B) 0x6468DFD: QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (in /usr/lib64/qt4/libQtCore.so.4.8.6)
| | | | | ->96.43% (1,986,843,600B) 0x64690F3: QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (in /usr/lib64/qt4/libQtCore.so.4.8.6)
| | | | | ->96.43% (1,986,843,600B) 0x646E557: QCoreApplication::exec() (in /usr/lib64/qt4/libQtCore.so.4.8.6)
| | | | | ->96.43% (1,986,843,600B) 0x409BDE: ??? (in /usr/bin/okular)
| | | | | ->96.43% (1,986,843,600B) 0x7788AA3: (below main) (in /lib64/libc-2.20.so)
Полный лог massif + ms_print - http://pastebin.com/raw.php?i=irEudVpd
gentoo, qt 4.8.6-r1, poppler 0.32.0, okular 4.14.3
Баг или фича?