воскресенье, 8 января 2012 г.

Утечки памяти и невозможность управлять памятью

Очень часто C++ упрекают в том, что в нем сложно управлять памятью. Постоянно программисты забывают освобождать указатели. Из-за этого падают программы, или в лучшем случае съедают много памяти. Сам часто делаю такие ошибки, благо современный инструментарий позволяет находить такие ошибки. Но самое главное, ты сам можешь управлять памятью. Хочешь - выделил, хочешь удалил. Свобода выбора.
Другое дело встроенные в ПО языки программирования. Например Oracle PL/SQL.
Последние пару месяцев довелось проводить нагрузочное тестирование продукта, работающего на Oracle 10g. Куча тестов, снятие трейсов, анализ трейсов. Рекомендации по оптимизации, патчи. Вроде все нормально. Но как обычно, пришел он. Писец. Процессы на базе данных съели всю память, PGA вырос до максимума, база встала. Налицо серьезная утечка памяти.
Первая мысль - сейчас возьмем какой-нибудь инструмент для oracle и найдем, что течет. Ха, нет такого. DBA говорят, что есть вроде тузла, но плохо документирована, и они её сами не знают. Поиск в гугле по возможному поиску утечек памяти говорит только об оном - снять дамп памяти с процесса и провести анализ. Что этот анализ даст не очень понятно.
Вторая мысль - у нас ведь есть код. Будем в нем искать. Но что может течь в pl/sql ? встроенные типы number, varchar ? более сложные структуры ? в pl/sql нет понятия деструктора. Присвоил переменной значение, попользовался, забыл. Oracle сам подчищает. Максимум для массивов можно и нужно вызывать удаление всех элементов. Плюс в некоторых пакетах, работающих с clob и xml, нужно вызывать методы очистки. Хотя по умолчанию, время жизни у них в пределах функции.
Поиск по коду, комментирование кусков кода и т.п. в итоге указало на массив с переменными типа xmltype. Но все было корректно с точки зрения кода. Печальный вывод - бага oracle.  Oracle сам управляет памятью, мы ничего не можем вручную удалить (кроме массива). При присвоениях переменным результата работы функции мы не знаем, что будет сделано с памятью - будет копирование, или присвоение указателя на кусок памяти. Мы отданы на милость Oracle и его баги.
Для подтверждения лезем на металинк и ищем похожие ошибки. И оказываемся не одинокими. Куча ошибок с утечкой памяти в xmltype. Патчи? не, вы обновитесь на 11g (задача не тривиальная, и требующая проверки всего кода на совместимость), там скорее всего нормально. А если нет, мы вам выпустим патч на 11g. И сплошь попытки найти ошибки в коде заявителей. К нашей радости, мы нашли обходной путь для очистки памяти.

Таким образом, за простотой работы с переменными, массивами и т.п. мы получаем  высокую  вероятность получить ошибку из-за проблем на стороне "виртуальной машины", исполняющей код. И отсутствие способов малой кровью исправить это. Единственный способ - хороший договор на поддержку со стороны разработчика "виртуальной машины".

FarColorer 1.0.3.7 и обновление схем



Как и обещал ранее, добавил совместимость с windows 2000 SP4. Вот одна из статей, где описано что нужно сделать в коде для компиляции в VC++ 2010 программ для windows 2000. Более интересный вариант от far group у меня поначалу не завелся, поэтому отказался от него.

Colorer 1.0.3.7 для Far 2
Colorer 1.0.3.7 для Far 3

Изменения
  1. совместимость с windows 2000 sp4 
Изменения схем
New:
- Go (Mikhail Kupchik)
- Far MacroLib (Max Rusov)
Fixed:
- NowDoc in PHP
- regexp
- C++ function outline
- far.hrc - new in Far3
- vbasic and vbscript - fix outline
- lua (Aidar, darkmist )
- cobol.hrc: updated keywords list, removed import, color all keywords the same, allow string in single or double quotes (Pavel Pleva)
- cobolfr.hrc: updated keywords list, removed import, color all keywords the same (Pavel Pleva)
- pl1.hrc: added preprocessor comments, removed import, and other (Pavel Pleva)

Измененные схемы так же можно скачать отдельно по ссылке hrc-update.2012-01-08.7z

среда, 4 января 2012 г.

Небольшое достижение

Вот такой подарок получил на новый год на месте работы.
P.S.  это не конкурс красоты -)