PL / SQL - проверить на утечки памяти? - PullRequest
3 голосов
/ 09 ноября 2010

У меня есть код PL / SQL, который, как мне кажется, может иметь утечку памяти. Каждый раз, когда я запускаю его, кажется, что он работает медленнее и медленнее, чем раньше, хотя сейчас я уменьшаю размер ввода. Код, который я подозреваю, это заполнение массива из курсора с помощью массового сбора, что-то вроде этого

    open c_myCursor(in_key);
         fetch c_myCursor bulk collect into io_Array; /*io_array is a parameter, declared as in out nocopy */
    close c_myCursor;

Я не уверен, как проверить, что вызывает это замедление. Я знаю, что в Oracle есть несколько таблиц, которые отслеживают такое использование памяти, но я не уверен, что можно посмотреть на эти таблицы и найти способ вернуться к чему-то полезному в том, что делает мой код.

Кроме того, я попытался выйти из сеанса и снова войти в систему через 10-15 минут, все еще очень медленно.

Версия Oracle 10.2


Так что оказывается была другая активность базы данных. Администратор БД решил выполнить несколько больших заданий на вставку и обновление примерно в то же время, когда я начал изменять и тестировать код. Я подозревал, что мой код был основной причиной, потому что мне не сказали о других запущенных работах (и я услышал об этой другой работе только после того, как она полностью заморозила все и все другие разработчики были раздражены). Вероятно, поэтому мой код становился все медленнее и медленнее.

Есть ли способ выяснить это программно, например, запросить сеанс вставки / обновления большого количества данных, на тот случай, если администратор базы данных забудет сообщить мне в следующий раз, когда он это сделает?

Ответы [ 4 ]

2 голосов
/ 12 ноября 2010

v $ sessmetric - это быстрый способ узнать, какие ресурсы использует каждый сеанс - процессор, физические_читания, логические_читания, pga_memory и т. Д.

2 голосов
/ 10 ноября 2010

"Я попытался выйти из сеанса и снова войти в систему примерно через 10-15 минут, все еще очень медленно."

Если вы используете обычное выделенное соединение на платформе * nix, это будет в значительной степениисключить любую утечку памяти.Когда вы устанавливаете новое соединение с базой данных, oracle отключит новый процесс для него, и вся память PGA будет принадлежать этому процессу, и она будет освобождена (ОС), когда сеанс будет отключен и процесс завершится.

Если вы используете соединения с общим сервером, тогда сеанс использует память, принадлежащую как процессу, так и разделяемой памяти.Это, вероятно, будет более уязвимо к любой проблеме утечки памяти.

Windows не работает так же, как и не обрабатывает отдельный процесс для каждого сеанса, а имеет отдельный поток под однимПроцесс Oracle.Опять же, я подозреваю, что это будет более уязвимо к утечке памяти.

Вначале я обычно искал другие проблемы и, вероятно, начинал с запроса, лежащего в основе c_myCursor.Может быть, он должен прочитать более старые данные, чтобы получить свежие данные?

0 голосов
/ 10 ноября 2010

Если ваш запрос возвращает очень много данных, ваша коллекция может вырасти до огромных размеров, скажем, 10 000 000 записей - это может быть причиной подозрительного использования памяти.

Вы можете проверить этопутем регистрации размера коллекции, в которую вы массово собираете.Если оно больше 10 000 (просто приблизительная оценка, это, конечно, зависит от данных), вы можете рассмотреть возможность разделения и работы с частями данных, например:

declare
  cursor cCur is select smth from your_table;
  --
  type TCur is table of cCur%rowtype index by pls_integer;
  --
  fTbl TCur;
begin
  open cCur;
  loop
    fTbl.delete;
    fetch cCur bulk collect into fTbl limit 10000;
    exit when cCur%notfound;

    for i in 1 .. fTbl.count loop
      --do your wok here
    end loop;
  end loop;
  close cCur;
end;

Поскольку вы сказали, что таблицаобъявлено как в нашей nocopy, я понимаю, что вы не можете напрямую переписать логику, подобную этой, а просто рассмотреть методологию, может быть, это может вам помочь.

0 голосов
/ 09 ноября 2010

http://www.dba -oracle.com / t_plsql_dbms_profiler.htm описывает DBMS_PROFILER. Я полагаю, что самые медленные части вашего кода могут быть связаны с утечкой памяти. В любом случае, если вы вернетесь к исходной проблеме, которая идет все медленнее и медленнее, то первое, что нужно сделать, это посмотреть, что медленно, а затем предположить утечку памяти.

Звучит так, будто вы не делаете коммит между выполнениями, а журнал повторов становится все больше и больше. Вероятно, это причина того, что БД должна обеспечивать согласованность чтения.

Вы также можете проверить консоль управления предприятием. Какую версию вы используете? Никогда не используйте XE для разработки, поскольку, насколько я знаю, профессиональная версия может быть использована для целей разработки. Консоль управления предприятием даже дает вам предложения. Может быть, он может рассказать вам кое-что умное о вашей проблеме с PLSQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...