Я запускаю сервер Perl с 10 потоками. Они никогда не уничтожаются, пока программа не выйдет, но это то, что я намереваюсь иметь как можно больше времени, поэтому вот почему это проблема для меня. Нитки обрабатывают простую задачу много раз. Когда я запускаю сервер, и все потоки запускаются, я вижу, что у меня 288,30 МБ бесплатно. После нескольких итераций через каждый поток он сообщает 285,96 МБ бесплатно. Это не так уж плохо. Может быть, это просто какое-то пространство стека, выделенное или что-то во время этих итераций. Но через 15 минут бесплатная память опускается до 248,24 МБ! Что случилось с моей памятью? Теперь, интересно, это плато. Он продолжает медленно потреблять, но не так быстро, как вначале. Я подумал, что, возможно, это была моя ошибка, поэтому я попытался дважды проверить объем всех моих переменных и даже не определить их всех в конце цикла потока.Перл потоков медленно потребляет память
Я распечатываю свободное пространство после КАЖДОЙ итерации нитей, поэтому я могу наблюдать за ней медленно. Теперь интересно также, что он не уменьшается каждый раз. Иногда свободная память остается неизменной после итерации.
Я использую Perl 5.8.8, построенный из источника на Linux 2.6
ли кто-нибудь есть какие-либо идеи на всех или даже предложения относительно того, что может быть причиной этого? Я рассматриваю возможность обновления моего Perl до более поздней версии, чтобы исключить утечку памяти в ядре Perl.
ОБНОВЛЕНИЕ: Может ли это быть проблемой размера стека? Могу ли я выделить больше памяти для стека, чем мне нужно. Когда я создаю свои потоки, я не изменяю настройку по умолчанию. Нужно ли мне? В документе docs указано, что значение по умолчанию обычно составляет 16 МБ в зависимости от системы. 16x10 threads = 160MB -> который может быть виновником. Мысли?
ОБНОВЛЕНИЕ: Я построил и установил Perl 5.12.1 и перестроил модули и все такое. Запустил скрипт около часа, и вот что я заметил. Использование памяти теперь управляемо, но не идеально.
- В начале сразу после нереста мои нити казались немного ниже. Вниз от ~ 60-66 МБ, выделенных для моих 10 потоков до ~ 45-50 МБ.
- После нескольких итераций их использование увеличилось на 3 МБ (примерно такое же, как и раньше).
- До этого момента я ожидал. Все это память заранее для нереста, а затем немного для переменных, которые я использую в своих потоках. Это та часть, которая мне не нравится. После работы около 10 минут, я теряю дополнительно 65 МБ! Почему он это делает? Если он уже повторил несколько раз штраф всего за 3 МБ, зачем продолжать выделять?
- На данный момент он работает полтора часа, и они больше не используют дополнительный 65 МБ, это еще 84 МБ!
- Это медленно занимает больше памяти, но странно, что количество свободной памяти не уменьшает каждую итерацию. Я распечатываю свободную память до и после каждой итерации, и она будет оставаться той же на некоторое время или навешивать + - вокруг определенного числа на некоторое время, а затем внезапно меняться на 5-10 МБ. Я не могу оставить эту работу более чем на один, два дня, потому что она начинает приближаться к 80/90% моей доступной памяти.
Есть ли другие идеи? Можно вообще попробовать? Я уже отказываюсь от всех переменных.
UPDATE: Я действительно хочу, чтобы перекомпилировать Perl с glibc в качестве последнего средства, так как я нашел несколько отчетов о том, что на некоторых вариантах Linux это будет segfault.Так как я последний раз опубликовал, я еще больше изучил возможность циклов в своих хэшах. Не нашел ничего. Поэтому я провел последние несколько дней, анализируя свою подпрограмму и кэшируя все, что используется на другой итерации. Многие новые вещи воссоздаются каждый раз, и Perl не очищает все это, даже если я явно отказываюсь от всего этого. Поэтому, если он не будет сотрудничать, я просто не уничтожу его. Посмотрите, поможет ли кеширование моих объектов. Позже опубликует статистику использования памяти.
ОБНОВЛЕНИЕ: Хм, очень странно. Даже после кэширования моих данных, которые будут использоваться повторно, память растет примерно с той же скоростью. Теперь он начинается выше, потому что я кеширую, но затем продолжает расти, хотя в основном я использую свои кешированные объекты. Это озадачивает. Угадайте, что пришло время попробовать glibc ... или это просто недостаток выбора Perl, и вам придется жить с перезагрузкой сервера каждые пару дней.
ОБНОВЛЕНИЕ: Пробовал без кеширования, без glibc, снова. Хорошо работает некоторое время, через несколько часов, затем он начинает расти. Просто хотел, чтобы вы увидели график.
http://tinypic.com/r/311nc08/3
http://i32.tinypic.com/311nc08.jpg
UPDATE: Вот выдержка из журнала регистрирующего свободной памяти до и после каждого потока в течение приблизительно минуты. Может быть, это поможет кому-то лучше понять проблему. Кажется, он немного стабилен, и тогда каждый так часто будет потреблять больше памяти. Здесь я теряю почти 40 МБ!
[9:8:30, Fri Jul 23, 2010] [0] Memory usage at end thread 1: 253.812736MB (obj cache: 136)
[9:8:30, Fri Jul 23, 2010] [0] Memory usage at idle thread 1: 253.812736MB (obj cache: 136)
[9:8:34, Fri Jul 23, 2010] [204] Sending data to thread
[9:8:34, Fri Jul 23, 2010] [0] 3 - Creating a new obj
[9:8:34, Fri Jul 23, 2010] [206] Sending data to thread
[9:8:34, Fri Jul 23, 2010] [0] 4 - Creating a new obj
[9:8:35, Fri Jul 23, 2010] [0] Memory usage at end thread 3: 253.812736MB (obj cache: 136)
[9:8:35, Fri Jul 23, 2010] [0] Memory usage at idle thread 3: 253.812736MB (obj cache: 136)
[9:8:35, Fri Jul 23, 2010] [0] Memory usage at end thread 4: 253.812736MB (obj cache: 136)
[9:8:35, Fri Jul 23, 2010] [0] Memory usage at idle thread 4: 253.812736MB (obj cache: 136)
[9:8:41, Fri Jul 23, 2010] [225] Sending data to thread
[9:8:41, Fri Jul 23, 2010] [0] 2 - Creating a new obj
[9:8:42, Fri Jul 23, 2010] [0] Memory usage at end thread 2: 253.681664MB (obj cache: 136)
[9:8:42, Fri Jul 23, 2010] [0] Memory usage at idle thread 2: 253.681664MB (obj cache: 136)
[9:8:47, Fri Jul 23, 2010] [243] Sending data to thread
[9:8:47, Fri Jul 23, 2010] [0] 1 - Creating a new obj
[9:8:48, Fri Jul 23, 2010] [0] Memory usage at end thread 1: 253.935616MB (obj cache: 136)
[9:8:48, Fri Jul 23, 2010] [0] Memory usage at idle thread 1: 253.935616MB (obj cache: 136)
[9:9:1, Fri Jul 23, 2010] [277] Sending data to thread
[9:9:1, Fri Jul 23, 2010] [0] 3 - Creating a new obj
[9:9:2, Fri Jul 23, 2010] [280] Sending data to thread
[9:9:2, Fri Jul 23, 2010] [0] 4 - Creating a new obj
[9:9:2, Fri Jul 23, 2010] [0] Memory usage at end thread 3: 253.935616MB (obj cache: 136)
[9:9:2, Fri Jul 23, 2010] [0] Memory usage at idle thread 3: 253.935616MB (obj cache: 136)
[9:9:3, Fri Jul 23, 2010] [283] Sending data to thread
[9:9:3, Fri Jul 23, 2010] [0] 2 - Creating a new obj
[9:9:4, Fri Jul 23, 2010] [284] Sending data to thread
[9:9:4, Fri Jul 23, 2010] [0] 1 - Creating a new obj
[9:9:4, Fri Jul 23, 2010] [0] Memory usage at end thread 2: 253.935616MB (obj cache: 136)
[9:9:4, Fri Jul 23, 2010] [0] Memory usage at idle thread 2: 253.935616MB (obj cache: 136)
[9:9:5, Fri Jul 23, 2010] [287] Sending data to thread
[9:9:5, Fri Jul 23, 2010] [0] 3 - Creating a new obj
[9:9:5, Fri Jul 23, 2010] [0] Memory usage at end thread 4: 253.93152MB (obj cache: 136)
[9:9:5, Fri Jul 23, 2010] [0] Memory usage at idle thread 4: 253.93152MB (obj cache: 136)
[9:9:6, Fri Jul 23, 2010] [290] Sending data to thread
[9:9:6, Fri Jul 23, 2010] [0] 2 - Creating a new obj
[9:9:7, Fri Jul 23, 2010] [0] Memory usage at end thread 3: 253.804544MB (obj cache: 136)
[9:9:7, Fri Jul 23, 2010] [0] Memory usage at idle thread 3: 253.804544MB (obj cache: 136)
[9:9:7, Fri Jul 23, 2010] [0] Memory usage at end thread 1: 253.804544MB (obj cache: 136)
[9:9:7, Fri Jul 23, 2010] [0] Memory usage at idle thread 1: 253.804544MB (obj cache: 136)
[9:9:9, Fri Jul 23, 2010] [0] 4 - Creating a new obj
[9:9:9, Fri Jul 23, 2010] [301] Sending data to thread
[9:9:9, Fri Jul 23, 2010] [0] 3 - Creating a new obj
[9:9:9, Fri Jul 23, 2010] [302] Sending data to thread
[9:9:9, Fri Jul 23, 2010] [0] 1 - Creating a new obj
[9:9:10, Fri Jul 23, 2010] [0] 3 - Creating a new obj
[9:9:11, Fri Jul 23, 2010] [0] 3 - Creating a new obj
[9:9:11, Fri Jul 23, 2010] [0] Memory usage at end thread 4: 253.93152MB (obj cache: 136)
[9:9:11, Fri Jul 23, 2010] [0] Memory usage at idle thread 4: 253.93152MB (obj cache: 136)
[9:9:12, Fri Jul 23, 2010] [308] Sending data to thread
[9:9:12, Fri Jul 23, 2010] [0] 4 - Creating a new obj
[9:9:13, Fri Jul 23, 2010] [0] Memory usage at end thread 1: 253.804544MB (obj cache: 136)
[9:9:13, Fri Jul 23, 2010] [0] Memory usage at idle thread 1: 253.804544MB (obj cache: 136)
[9:9:14, Fri Jul 23, 2010] [0] Memory usage at end thread 4: 253.804544MB (obj cache: 136)
[9:9:14, Fri Jul 23, 2010] [0] Memory usage at idle thread 4: 253.804544MB (obj cache: 136)
[9:9:14, Fri Jul 23, 2010] [0] Memory usage at end thread 3: 253.93152MB (obj cache: 136)
[9:9:14, Fri Jul 23, 2010] [0] Memory usage at idle thread 3: 253.93152MB (obj cache: 136)
[9:9:15, Fri Jul 23, 2010] [313] Sending data to thread
[9:9:15, Fri Jul 23, 2010] [0] 1 - Creating a new obj
[9:9:16, Fri Jul 23, 2010] [0] Memory usage at end thread 2: 214.482944MB (obj cache: 136)
[9:9:16, Fri Jul 23, 2010] [0] Memory usage at idle thread 2: 214.482944MB (obj cache: 136)
[9:9:16, Fri Jul 23, 2010] [315] Sending data to thread
[9:9:16, Fri Jul 23, 2010] [0] 4 - Creating a new obj
[9:9:17, Fri Jul 23, 2010] [0] Memory usage at end thread 1: 214.355968MB (obj cache: 136)
[9:9:17, Fri Jul 23, 2010] [0] Memory usage at idle thread 1: 214.355968MB (obj cache: 136)
[9:9:18, Fri Jul 23, 2010] [316] Sending data to thread
[9:9:18, Fri Jul 23, 2010] [0] 3 - Creating a new obj
[9:9:18, Fri Jul 23, 2010] [317] Sending data to thread
[9:9:18, Fri Jul 23, 2010] [0] 2 - Creating a new obj
[9:9:18, Fri Jul 23, 2010] [318] Sending data to thread
[9:9:18, Fri Jul 23, 2010] [0] 1 - Creating a new obj
[9:9:19, Fri Jul 23, 2010] [0] Memory usage at end thread 4: 214.355968MB (obj cache: 136)
[9:9:19, Fri Jul 23, 2010] [0] Memory usage at idle thread 4: 214.355968MB (obj cache: 136)
[9:9:19, Fri Jul 23, 2010] [0] Memory usage at end thread 1: 214.355968MB (obj cache: 136)
[9:9:19, Fri Jul 23, 2010] [0] Memory usage at idle thread 1: 214.355968MB (obj cache: 136)
[9:9:20, Fri Jul 23, 2010] [0] Memory usage at end thread 3: 214.482944MB (obj cache: 136)
[9:9:20, Fri Jul 23, 2010] [0] Memory usage at idle thread 3: 214.482944MB (obj cache: 136)
[9:9:20, Fri Jul 23, 2010] [0] Memory usage at end thread 2: 214.482944MB (obj cache: 136)
[9:9:20, Fri Jul 23, 2010] [0] Memory usage at idle thread 2: 214.482944MB (obj cache: 136)
UPDATE (8/12/2010): Просто побежал за один день с новой скомпилированной версии Perl 5.12 с потоками и системы таНос. Странно, я получаю такое же поведение. Потеряйте кусочки МБ за раз, медленно. Можете попробовать Valgrind, чтобы понять, почему я теряю его. Пока я играл с чем-то другим, хотя я думал о чем-то другом. Мой скрипт создает и уничтожает (предположительно) много SSL-сокетов. Возможно ли, что широко используемый модуль, такой как IO :: Socket :: SSL, немного течет? Или, может быть, OpenSSL? (Использование v0.9.8o). Чтобы попробовать синхронизировать доступ к модулю SSL, чтобы увидеть, имеет ли он какой-либо эффект, могут возникнуть проблемы с доступом к ним.
ОБНОВЛЕНИЕ: Пробная загрузка модулей отдельно в каждом потоке, более быстрое использование памяти. Пробовал блокировать области с помощью функций сокетов, поэтому только один поток за раз использовал их, все еще потерял память так же, как и раньше. Увеличилось число рабочих потоков с 4 до 10 с одинаковым объемом работы. Память не длилась 30 минут. Позволяет мне думать, что это либо проблема Perl внутри страны с реализацией потока, либо проблема стека (каламбур не предназначен). Я попытался изменить размер стека, используя встроенные методы потока, но тот же результат. Идти искать другой путь. Возможно, более низкий уровень. Увеличение количества потоков заставляет память ускоряться ... похоже, что-то с реализацией стека нитей или размером стека
ОБНОВЛЕНИЕ (9/15/2010): Обнаружил этот интересный лабиринт в IO :: Socket :: SSL doc ...
Это связано с тем, что для того, чтобы сделать IO :: Socket :: SSL-сокеты, действуют одновременно как объекты и ссылки на glob.
"Циркулярная ссылка" да? Еще одно возможное объяснение заключается в том, что эти сокеты все время прилипают к нему, хотя я явно не отказался от них. Заглядывайте в Weaken, чтобы узнать, не делает ли это что-либо с сокетами. Сообщите, найду ли я что-нибудь интересное.
РЕШИТЬ (9/16/2010): Смотрите мой ответ, что я отправил, содержащий раствор
Опубликовать код или найти круглые ссылки: P –
Вы посмотрели на этот вопрос: http://stackoverflow.com/questions/429254/how-can-i-find-memory-leaks-in-long-running -perl-program – dwarring
Возможный дубликат [Использование профилей памяти Perl и обнаружение утечки?] (http://stackoverflow.com/questions/1359771/perl-memory-usage-profiling-and-leak-detection) – Ether