Оперативное вмешательство: разбираемся с утечками памяти

    Оперативной памяти много не бывает: любой доступный объём достаточен лишь «до поры, до времени», а там найдётся, куда его применить. Хорошо, когда это действительно полезные задачи. Работа. Игры. Исследования. Плохо, когда оперативка заканчивается не по вине пользователя, но по раздолбайству разработчика.



    Причин тому много, способов же решения… давайте обо всём по порядку.

    Верните мой 97-й


    Незаконный захват оперативной памяти приложениями – прямое следствие технологического прогресса. Вычислительных ресурсов, спасибо закону Мура, становится больше (да и цена их падает год от года), а стоимость работы высококвалифицированного специалиста, увы (и вновь к счастью для нас, IT'шников), следует обратной динамике. Приложения обрастают новыми возможностями, для быстрой разработки вводятся очередные слои абстракций… Двадцать лет назад код был куда ближе к «железу», нежели сейчас. Огромное число прослоек и промежуточных технологий – одно из многих зол, приводящих к плачевной ситуации. 15 мегабайт оперативной памяти для (!) калькулятора. Кошмар!



    И ладно бы ситуация улучшалась, так нет: разработчики берут старые инструменты, придумывают еще более простые и многофункциональные новые, проходит несколько лет и цикл повторяется. Подумать только, недавно мы радовались CSS 3.0 и скругленным уголкам простым свойством объекта, затем Bootstrap'у, сейчас – очередной надстройке-комбайну. Write less, do more во все поля.

    Комфортабельные троллейбусы из хлеба


    Современные браузеры – это не только ценный гипертекст, но и три-четыре десятка полезных фич. Воспроизведение видео, работа с документами, и другие расширения – почти что операционка в миниатюре. С кучей собственных модулей от разных разработчиков, и всё это соединено кое-как. Работает зачастую так же. Миллион открытых вкладок, сложная вёрстка, фреймворк на фреймворке – одни из основных генераторов утечек.

    Как бороться? Поставить какой-нибудь блокировщик рекламы и экстеншн типа The Great Suspender, который выгружает из памяти неиспользуемые страницы и сохраняет во вкладке «минимум» – удобно и эффективно снижает фоновый отжор памяти.



    Не все adblock'и одинаково полезны


    Да, софт, который вырезает назойливые баннеры и код всяких отслеживалок, в определенных случаях снижает нагрузку и на процессор, и на оперативку. Но не всегда. Эффективность данного решения зависит напрямую от качества его исполнения. Софт, работающий на уровне системы в роли прокси-сервера (отсекающий трафик с рекламных площадок до того, как он попадёт в браузер) сам по себе потребляет некоторый объём памяти, но он более-менее статичен. А вот расширения и модули для популярных браузеров создают монструозные конструкции на месте вырезанных рекламных фреймов. Да, рекламы на странице становится меньше, вот только потребление памяти данной вкладкой может вырасти не на каких-то 10-15%, а в несколько раз.

    Проблемы кэширования ресурсов


    Этим страдают в большинстве своём игры-песочницы, как стационарные, так и запускаемые внутри браузера: Factorio, Rim World, Minecraft с кучей модов… При определённом стечении обстоятельств (например, оставили производство на ночь, чтобы игра зарабатывала, пока вы спите) можно проснуться с наглухо повисшим компьютером. Ну или очень медленно работающим. При этом в плане оперативной памяти всё будет «ок» – сколько потребляла игра, столько и потребляет.



    В 90% случаев такого поведения у пользователей установлен SSD и включены одновременно файл подкачки и режим гибернации. Игра сбрасывает неиспользуемые ресурсы из оперативки в своп, «Винда» кэширует их и сохраняет на случай ухода в сон, далее графика используется повторно и вновь откладывается в «долгий ящик». Вот только старые копии никуда не удаляются – спустя несколько часов, в зависимости от объёма накопителя, свободное место на нём заканчивается, система падает до перезагрузки и очистки временных файлов. Не пытайся игра «оптимизировать» расход оперативной памяти, выгружая и вновь подкачивая ресурсы – текла бы как обычно, с постепенным замедлением работы и последующим крашем.



    Варианты решения: проверка гипотезы какой-нибудь утилитой типа TreeSize, удаление накопленных мусорных asset'ов, перенос подкачки на объёмный HDD или отключение гибернации в Windows 10, написание багрепорта на форум, ожидание патча.

    У разработчика лапки


    Иногда утечки – это просто утечки. Фотошоп любит и умеет отжирать большие объёмы памяти, особенно сразу после выхода нового номерного релиза. Благо в самом приложении есть инструмент ограничения доступного объёма оперативки (не стоит выделять больше 66%), назначения кэширующих дисков и всего такого. В качестве альтернативы можно подождать полгода и дождаться стабильной версии. Киллерфичи редко бывают настолько нужны, чтобы мириться с багами.



    Торрент-клиенты. Множество одновременно установленных подключений, столько же одновременно скачиваемых файлов, проблемы с соединением – и соответствующий расход памяти. Решение – ограничение на количество исходящих соединений и скорости отдачи. Правильные коэффициенты подбираются вручную.

    Софт принтеров / сканеров / камер. В анамнезе – написанный за еду индусский код: кривой, как камасутра. Медицина в этом случае бессильна – тут уж ибо использовать открытые / универсальные аналоги, либо писать багрепорты и молиться Шиве, чтоб тот покарал проклятых халтурщиков.



    Майнер-малварь. Иногда утечка памяти «в никуда» – повод расчехлить антивирус. Главная защита криптовалют от «оптимизации» их добычи аппаратным методом – увеличение сложности алгоритма в направлении «нужно больше памяти для расчётов». Поэтому фоновые майнилки могут спалиться на потреблении оперативки. Причём приобщиться к числу «шахтёров» можно и незаметно для себя: чего стоит только известный скандал с uTorrent, «бонусом» к которому пользователи получали приложение-майнер Epic Scale. Да и один популярный трекер минувшей осенью засветился в фоновой добыче криптовалюты прямо в браузерах посетителей.



    Война без конца


    Пройдёт ещё немало времени до того, как будет написан качественный ИИ, способный разгрести завалы кривого кода. А пока приходится бороться с утечками памяти проверенными методами: с бубном, плетью и багрепортом. Или наращивать объёмы и не замечать этих самых утечек. Конечно, иметь на борту 16, 32 или даже 64 гига быстрой оперативки – это хорошо, и у Kingston всегда найдётся подходящее решение. Важно помнить, что кривому софту любой объём не помеха – просто с хорошим запасом оперативной памяти он дольше проработает без проблем.

    Есть интересные примеры утечек памяти в системе? Пишите в комментах – всем будет интересно.
    Kingston Technology 78,47
    Компания
    Поделиться публикацией
    Комментарии 20
    • 0
      Двадцать лет назад было то же самое — калькулятор, занимавший сотни килобайт в памяти и на диске, когда можно было реализовать тот же функционал в десятке килобайт. И так же как и сейчас — никого это не волновало. Нет, ну серьезно, у меня компьютер 2014г., на нем 32 гигабайта оперативки. Я могу хоть две тысячи калькуляторов запустить не затрагивая файл подкачки, который лучше жестко задать или вовсе отключить.

      Меня куда больше изумляет dwm, который не стесняясь «отъедает» почти гигабайт — зачем ему столько?! Нет, мне не жалко, но сам факт…
      • 0
        dwm, который не стесняясь «отъедает» почти гигабайт — зачем ему столько?!
        А у него утечка памяти. Помню такое было на драйверах AMD и/или каких-то Nvidia. Просто убей его в процессах и он запустится заново без мусора.
        • 0
          Калькулятор в Win7 занимает 4280 кб, но съедает по 4 кб (!) на каждую операцию. зачем? как вы это написали? он же не запоминает их.
          Да иногда и системные требования программ уровня ~ текстового редактора изумляют по размеру ОЗУ, причём корреляция идёт с известностью бренда, любительские проги явно меньше жрут при схожем функционале.
          • 0
            На самом деле, критикующие калькулятор за 15 мегабайт, забывают, что FullHD картинка (1920х1080 32 бита) занимает 7 мегабайт. Соответственно, если приложение хочет быстро рисовать, оно должно хранить область памяти для рисования.

            А ещё нужно где-то хранить области памяти для рендеринга шрифтов и кнопочек. И это всё — o(n2) от размера.

            Понятно, что есть масса техник оптимизации. Но некоторые из них требуют жертв со стороны пользователя (см IE'шную картинку в посте) — например, если не хранить память а рисовать «on demand», то если приложение зависло, то оно больше не перерисовывает экран.

            • 0
              то если приложение зависло, то оно больше не перерисовывает экран.

              Кажется это решили ещё со времён висты.
              • 0
                Именно. А решили её простым образом: теперь программы не перерисовывают экран по любому чиху, а винда хранит копию того, что там было нарисовано.

                Раньше программе присылали invalidate и она перерисовывала. Памяти при этом тратилось мало. Т.к. всех пользователей такое поведение программы сильно раздражало, то сделали иначе: есть копия картинки от программы. Это означает, что к каждой программе (окну!) дописали N мегабайт памяти на хранение.

                Это частичный ответ на вопрос. Всякие ценители досовых программ в единицы килобайт часто забывают, что в те времена 640х480 8 бит было уже круто и красиво.
          • 0
            Фотошоп любит и умеет отжирать большие объёмы памяти <...> Благо в самом приложении есть инструмент ограничения доступного объёма оперативки (не стоит выделять больше 66%)

            Вообще оптимальный уровень около 60-75% для всех новых версий (лучше оставить по умолчанию 70), при этом сама Adobe не рекомендует ставить больше 85%. Ну это я так, к слову.
            • 0

              Сколько себя помню — нытье было всегда :)
              Даже когда я в 91м заполучил самый настоящий PС/XT (640Кб 4.77Мгц, все дела), пересев на него со Спектрума, местные умельцы (дядьки на 10-15 лет постарше) ходили ко мне на тусу "потоптать писюк" и фыркали при виде 20Мб винта, под завязку забитого барахлом типа BorlandC 3.0, который работал там с дичайшим скрипом, и сокрушались, вот мол, никакой экономии места, программы неоптимизированны, борландовский компилятор подтягивал с собою кучу "ненужных" либ, то ли дело они в 48Кб укладывали и игры и даже какие-то электронные таблицы. :)


              Хотя моя первая относительно полноценная разработка (которая хоть что-то полезное делала) — квази-клон старого доброго King's Bounty в EGA-палитре (на стандартных борландовских egavga.bgi, уже на 386м проце где-то в 93 или 94м) занимал аж 160Кб (это только EXE!) и я прям-таки физически страдал от того, что при таком минимуме функционала файл получался такой жирный.


              А щас ничо, почти привык уже к тому, что 64-битный Хром может на полусотне вкладок отожрать гигов 16 памяти и не подавиться.
              Поэтому, подзадушив жабу, раз в несколько подтыкиваю еще один модуль оперативки в плату. Уже насобирал 48Гб, пока хватает. Память, кстати… кхм-хм та самая, с красной небритой башкой на коробочке.

              • 0
                500*7Мб = 3500 Мб. Это только чтобы хранить вкладки в памяти. А 7Мб — см выше, это всего лишь содержимое FullHD экрана.
                • 0

                  "полсотни" — это все же 50, а не 500 :)

                  • 0
                    Да, пардон. Но и размер страницы надо считать с учётом области прокрутки. Там всё сложнее, но, в целом, если на странице 30 экранов скроллинга картинок, это это 237 мегабайт. Не считая dom, js и прочих штук.
                    • 0

                      Да я ж не спорю, что нынешние свистелко-перделки в браузерах только на уровне рендера DOM занимает немало ОЗУ, не говоря уже о запросах JS или модулей типа баннерорезок.
                      И отлично понимаю, какое количество человеко-часов может уйти на то, чтобы (как некоторые ратуют) "оптимизировать" браузер, написав его чуть ли не на ассемблере без "этих ужасных фреймворков" — про это просто можно (а точнее нужно) забыть — затея совсем так себе.


                      Растущие аппетиты софта компенсируются ростом аппаратной части. И собственно, этот симбиоз и двигает прогресс.
                      Можно конечно повздыхать и покивать на древнюю аппаратуру "Вояджера", где в считанные килобайты памяти умудряются впихнуть невпихуемое.
                      Или покивать на парней, которые умудрялись делать шедевры на плойке, где каждый байт был на счету (где-то тут была увлекательнейшая статья на эту тему).
                      Но… Не буду :)

                      • 0
                        Я хочу сделать упор на то, что помимо аппетитов программистов, есть ещё аппетиты пользователей, которые хотят 4к экраны с мгновенным переключением между табами и окнами. А это объективные сотни мегабайт/гигабайты. В отрыве от прочих структур данных.

                        • 0

                          С очевидным невозможно спорить.

              • +1
                Задолбала TMG2010 по поводу утечек памяти. Причем текла не просто память, а nonpaged pool — как оказалось, TMG некорректно обрабатывала пакеты специфической структуры, не до конца подчищая ресурсы дескрипторов соединений, как следствие, комп начинал тормозить, терять новые соединения и потом зависал до хард-резета. Приходилось его ребутать раз в месяц (по опыту, где-то за 30 дней вся память утекала, как раз получалось).
                • 0
                  В 90% случаев такого поведения у пользователей установлен SSD и включены одновременно файл подкачки и режим гибернации. Игра сбрасывает неиспользуемые ресурсы из оперативки в своп, «Винда» кэширует их и сохраняет на случай ухода в сон, далее графика используется повторно и вновь откладывается в «долгий ящик». Вот только старые копии никуда не удаляются – спустя несколько часов, в зависимости от объёма накопителя, свободное место на нём заканчивается, система падает до перезагрузки и очистки временных файлов.


                  Это действительно так работает? Зачем что то сохранять на случай ухода в сон? Питание ОЗУ не отключаеться а значит все можно хранить так же как и раньше. И вобще, при чем тут ССД? У меня такое было и на ХДД (режим гибернации и файл подкачки).
                  • 0
                    Питание ОЗУ не отключаеться

                    Так было в XP с ждущим режимом. Начиная с висты есть гибридный спящий режим, где память сбрасывается на диск, но питание ОЗУ отключается не сразу.
                    • 0
                      Вы не правы.
                      Есть ражим:
                      гибернации,
                      спящий,
                      гибридный

                      Так вот. Гибридный режим это когда при переходе в спящий режим данные дублируються и на жестком диске и в случае отключения питания компьютер включиться так же как это было бы при выходе из режима гибернации. Если компютер не отключать то он возобновит работу так же как и после обычного спящего режима — то есть через несколько секунд.
                      • 0
                        Это проблема разных переводов, зачастую неудачных.
                        Кстати, вы описали именно гибридный спящий режим, по сути пересказ моих слов.
                  • 0
                    Ха. Мессенджер, кушающий 200+ МБайт ОЗУ не хотите?
                    Скайп.
                    Особенно учитывая его убитый в хлам в новой версии функционал — из цензурных слов только молчание и остается.

                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                    Самое читаемое