Re[4]: Жизнь после OutOfMemory ?
От: leokom Украина http://neformatc.blogspot.com
Дата: 21.02.08 10:58
Оценка:
Здравствуйте, jitm, Вы писали:

DZ>>
  • ОМЕ может случиться в любой точке программы, где создается новый объект. Невозможно заранее предсказать где;
    J>Ну это я понимаю прекрасно но автор топика как — то это думает побороть раз задал такой вопрос иначе наше обсуждение просто флейм ...

    Может случиться в любой точки программы — но в main — методе можно перехватить и попытаться пройдясь по объектам программы, присвоить null тем что не нужны. Но чтобы это реализовать придётся имплементить довольно сложный менеджер ресурсов — что есть геморройно.
    Излишнее цитирование удалено. Обратите внимания на правила форума. В случае дальнейшего их нарушения ваши права на RSDN могут быть ограничены режимом read-only.
  • Re[7]: Жизнь после OutOfMemory ?
    От: leokom Украина http://neformatc.blogspot.com
    Дата: 21.02.08 11:02
    Оценка:
    Здравствуйте, denis.zhdanov, Вы писали:

    DZ>Здравствуйте, leokom, Вы писали:


    L>>Видимо это "решение" действительно не будет работать так как вирт. машина перед броском этого иксепшна сама попыталась "собрать мусор"... Вопрос в том имеет ли смысл ловить такой иксепшн и например пытаться ручками за-null-ить какие-то возможно ненужные объекты, а потом "попросить" вирт. машину снова "поубирать" (только попросить так как гарантий выполнения сборщика она не дает). Или после OutOfMemory работа вирт. машины вообще неопределенна, и лучше всего закрыть аппликейшн?


    DZ>Т.к. ОМЕ может случиться где угодно, возможен вариант, что если ты даже поймаешь еррор в месте, откуда можно занулить ссылки на большие объекты, не факт что ОМЕ не вылетела перед этим в другом потоке(ах). Т.е. если ты поймаешь и освободишь память, у тебя могут быть unexpectedly terminated важные потоки.


    DZ>Расскажи лучше о задаче, в качестве возможного решения которой ты рассматриваешь обработку ОМЕ. Я уверен, что можно будет предложить лучшую альтернативу.


    Задача — получение данных из внешнего хранилища (веб-сервис), конвертация в формат базы и сохранение. Прога многопоточная, количество потоков заранее не детерминировано — по одному потоку на данные одной организации зарегистрированной в веб-сервисе, а количество организаций не фиксированное.
    Веб-сервис тупой — присылает данные большими потоками (десятки метров), пейджинг у него не реализован (то есть отфильтровать по дате или как-то еще не получится).
    Много потоков * много памяти на каждый поток --> OutOfMemory (не постоянно ... но случается)
    Re[4]: Жизнь после OutOfMemory ?
    От: leokom Украина http://neformatc.blogspot.com
    Дата: 21.02.08 11:04
    Оценка:
    Здравствуйте, jitm, Вы писали:

    J>Да, но у меня встречный вопрос если ты хош ловить ООМЕ то ты знаешь де оно происходит ? Если знаешь то может просто не доводить до ООМЕ, как ты на это смотришь ? Если не знаешь то ты либо пишешь так как описал denis.zhdanov либо тебе стало скучно и ты решил поговорить


    http://rsdn.ru/forum/message/2847579.1.aspx
    Автор: leokom
    Дата: 21.02.08

    Излишнее цитирование удалено. Обратите внимания на правила форума. В случае дальнейшего их нарушения ваши права на RSDN могут быть ограничены режимом read-only.
    Re[5]: Жизнь после OutOfMemory ?
    От: Blazkowicz Россия  
    Дата: 21.02.08 11:05
    Оценка:
    Здравствуйте, leokom, Вы писали:

    L>Может случиться в любой точки программы — но в main — методе можно перехватить

    Через main метод идет единственый стартующий поток. Рекомендую задуматься над
    — Не все приложения однопоточны
    — Исключения не вываливаются за рамки потоков
    Хотя вроде есть какое-то решение.

    L>Но чтобы это реализовать придётся имплементить довольно сложный менеджер ресурсов — что есть геморройно.

    Это будет второй GC, только в контексте твоего приложения. Гораздо лучшим решением будет анализ работы приложения под нагрузкой и соответствующая настройка GC.
    Re[6]: Жизнь после OutOfMemory ?
    От: leokom Украина http://neformatc.blogspot.com
    Дата: 21.02.08 11:11
    Оценка:
    Здравствуйте, Blazkowicz, Вы писали:

    B>Здравствуйте, leokom, Вы писали:


    L>>Может случиться в любой точки программы — но в main — методе можно перехватить

    B>Через main метод идет единственый стартующий поток. Рекомендую задуматься над
    B> — Не все приложения однопоточны
    B> — Исключения не вываливаются за рамки потоков
    B>Хотя вроде есть какое-то решение.

    L>>Но чтобы это реализовать придётся имплементить довольно сложный менеджер ресурсов — что есть геморройно.

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

    Приложение действительно многопоточное
    Исключения не вываливаются за рамки потоков — это действительно так, но не "ломают" ли они вирт. машину (конкретно наследники Error)?
    Re[8]: Жизнь после OutOfMemory ?
    От: jitm  
    Дата: 21.02.08 11:13
    Оценка: 3 (1)
    Здравствуйте, leokom, Вы писали:

    L>Здравствуйте, denis.zhdanov, Вы писали:



    L>Задача — получение данных из внешнего хранилища (веб-сервис), конвертация в формат базы и сохранение. Прога многопоточная, количество потоков заранее не детерминировано — по одному потоку на данные одной организации зарегистрированной в веб-сервисе, а количество организаций не фиксированное.

    L>Веб-сервис тупой — присылает данные большими потоками (десятки метров), пейджинг у него не реализован (то есть отфильтровать по дате или как-то еще не получится).
    L>Много потоков * много памяти на каждый поток --> OutOfMemory (не постоянно ... но случается)
    Ну что я тебе могу сказать в теории нету багов в программах а есть баги в ДНК, что это значит: пересмотрите свою архитектуру так как вы пытаетесь лечить последствия а нужно лечить причину! Тогда тебе и не нужно будет придумывать что — то сверх естественное для закрытия этой дырки, это не есть генеально или хорошо так как генеальность высказывается в простоте!
    Re[8]: Жизнь после OutOfMemory ?
    От: Blazkowicz Россия  
    Дата: 21.02.08 11:14
    Оценка:
    Здравствуйте, leokom, Вы писали:

    L>Задача — получение данных из внешнего хранилища (веб-сервис), конвертация в формат базы и сохранение. Прога многопоточная, количество потоков заранее не детерминировано — по одному потоку на данные одной организации зарегистрированной в веб-сервисе, а количество организаций не фиксированное.

    L>Веб-сервис тупой — присылает данные большими потоками (десятки метров), пейджинг у него не реализован (то есть отфильтровать по дате или как-то еще не получится).
    L>Много потоков * много памяти на каждый поток --> OutOfMemory (не постоянно ... но случается)
    Веб сервисы надо полагать поверх HTTP? Так может не вычитывать данные все сразу а читать последовательно через InputStream? И настроить клиент так чтобы размер буфера был лимитирован?

    А так рецепт один. Надо настроить JVM чтобы она тебе по OME вываливада дамп памяти и потоков. Потом тебе нужно будет их проанализировать и обнаружить кто засрал всю память. DOM случаем для парсинга XML SOAP не используется?
    Re[7]: Жизнь после OutOfMemory ?
    От: Blazkowicz Россия  
    Дата: 21.02.08 11:17
    Оценка: 6 (2)
    Здравствуйте, leokom, Вы писали:

    L>Приложение действительно многопоточное

    L>Исключения не вываливаются за рамки потоков — это действительно так, но не "ломают" ли они вирт. машину (конкретно наследники Error)?
    Нет, они не ломают JVM. Но просто OEM приводит к каскадному краху в многопоточном приложении. Обваливается только один поток. Остальные про это не знают, работают дальше и соответственно обваливаются один за одним. Я единственное в твоем случае не понял кто инициирует создание потоков? Может перет тем как запускать каждый новый поток, смотреть как дела с памятью и вешать его, на какой-то период времени. Естественно не забыв про таймаут.
    Re[8]: Жизнь после OutOfMemory ?
    От: C0s Россия  
    Дата: 21.02.08 11:26
    Оценка: 5 (3)
    Здравствуйте, leokom, Вы писали:

    L>Задача — получение данных из внешнего хранилища (веб-сервис), конвертация в формат базы и сохранение. Прога многопоточная, количество потоков заранее не детерминировано — по одному потоку на данные одной организации зарегистрированной в веб-сервисе, а количество организаций не фиксированное.


    иметь количество потоков нефиксированным, полагаю, неверно. оно ведь зависит от аппаратуры, а не от количества организаций.
    Re[8]: Жизнь после OutOfMemory ?
    От: leokom Украина http://neformatc.blogspot.com
    Дата: 21.02.08 11:33
    Оценка:
    Здравствуйте, Blazkowicz, Вы писали:

    B>Нет, они не ломают JVM. Но просто OEM приводит к каскадному краху в многопоточном приложении. Обваливается только один поток. Остальные про это не знают, работают дальше и соответственно обваливаются один за одним. Я единственное в твоем случае не понял кто инициирует создание потоков? Может перет тем как запускать каждый новый поток, смотреть как дела с памятью и вешать его, на какой-то период времени. Естественно не забыв про таймаут.


    Спасибо, буду разгребать. Потоки создаются библиотекой Quartz (планировщик)
    Излишнее цитирование удалено. Обратите внимания на правила форума. В случае дальнейшего их нарушения ваши права на RSDN могут быть ограничены режимом read-only.
    Re[9]: Жизнь после OutOfMemory ?
    От: leokom Украина http://neformatc.blogspot.com
    Дата: 21.02.08 11:34
    Оценка:
    Здравствуйте, jitm, Вы писали:

    J>Ну что я тебе могу сказать в теории нету багов в программах а есть баги в ДНК, что это значит: пересмотрите свою архитектуру так как вы пытаетесь лечить последствия а нужно лечить причину! Тогда тебе и не нужно будет придумывать что — то сверх естественное для закрытия этой дырки, это не есть генеально или хорошо так как генеальность высказывается в простоте!


    Спасибо, будем пытаться разгребать. Просто мы зависим от веб-сервиса который криво писали не мы
    Излишнее цитирование удалено. Обратите внимания на правила форума. В случае дальнейшего их нарушения ваши права на RSDN могут быть ограничены режимом read-only.
    Re[9]: Жизнь после OutOfMemory ?
    От: leokom Украина http://neformatc.blogspot.com
    Дата: 21.02.08 11:36
    Оценка:
    Здравствуйте, Blazkowicz, Вы писали:

    B>Веб сервисы надо полагать поверх HTTP? Так может не вычитывать данные все сразу а читать последовательно через InputStream? И настроить клиент так чтобы размер буфера был лимитирован?

    B>А так рецепт один. Надо настроить JVM чтобы она тебе по OME вываливада дамп памяти и потоков. Потом тебе нужно будет их проанализировать и обнаружить кто засрал всю память. DOM случаем для парсинга XML SOAP не используется?

    К веб-сервису достукиваемся через Axis... Спасибо еще раз. Буду пробовать.
    Излишнее цитирование удалено. Обратите внимания на правила форума. В случае дальнейшего их нарушения ваши права на RSDN могут быть ограничены режимом read-only.
    Re[7]: Жизнь после OutOfMemory ?
    От: sss1024 http://microforms.mobile-mir.com/
    Дата: 21.02.08 11:51
    Оценка:
    L>Приложение действительно многопоточное
    L>Исключения не вываливаются за рамки потоков — это действительно так, но не "ломают" ли они вирт. машину (конкретно наследники Error)?

    да не ломают они ничего (это из практики а не теории). К тому же ты знаешь где примерно это происходит. Просто ловить исключение нужно не в маин а там где создаются потоки на получение данных. При исключении остановиться и подождать пока остальные потоки данные перекачают и освободят ресурсы. Делов-то

    Но по уму конечно в такой ситуации лучше поменять саму архитектуру, например принятые данные складывать на диск сначала
    Re[10]: Жизнь после OutOfMemory ?
    От: Blazkowicz Россия  
    Дата: 21.02.08 11:52
    Оценка:
    Здравствуйте, leokom, Вы писали:

    L>К веб-сервису достукиваемся через Axis... Спасибо еще раз. Буду пробовать.

    А формат у веб-сервиса сильно фиксированый, или руглярно меняется? Для фиксированых форматов имеет смысл переписать все на HTTP + SAX, посмотреть так же альтернативные клиентские решения для SOAP, которые может быть парсят XML оптимальнее. Короче тут можно вообще развернутся очень сильно и опитимизировать долго и упорно.
    Re[11]: Жизнь после OutOfMemory ?
    От: leokom Украина http://neformatc.blogspot.com
    Дата: 21.02.08 13:26
    Оценка:
    Здравствуйте, Blazkowicz, Вы писали:

    B>Здравствуйте, leokom, Вы писали:


    L>>К веб-сервису достукиваемся через Axis... Спасибо еще раз. Буду пробовать.

    B>А формат у веб-сервиса сильно фиксированый, или руглярно меняется? Для фиксированых форматов имеет смысл переписать все на HTTP + SAX, посмотреть так же альтернативные клиентские решения для SOAP, которые может быть парсят XML оптимальнее. Короче тут можно вообще развернутся очень сильно и опитимизировать долго и упорно.

    Большое спасибо за советы! Формат фиксированный. Буду пробовать альтернативы
    Re[8]: Жизнь после OutOfMemory ?
    От: leokom Украина http://neformatc.blogspot.com
    Дата: 21.02.08 13:28
    Оценка:
    Здравствуйте, sss1024, Вы писали:

    L>>Приложение действительно многопоточное

    L>>Исключения не вываливаются за рамки потоков — это действительно так, но не "ломают" ли они вирт. машину (конкретно наследники Error)?

    S>да не ломают они ничего (это из практики а не теории). К тому же ты знаешь где примерно это происходит. Просто ловить исключение нужно не в маин а там где создаются потоки на получение данных. При исключении остановиться и подождать пока остальные потоки данные перекачают и освободят ресурсы. Делов-то


    S>Но по уму конечно в такой ситуации лучше поменять саму архитектуру, например принятые данные складывать на диск сначала


    Большое спасибо за обсуждение. Будем обдумывать архитектуру и возможность замены клиентских библиотек (мы на них завязаны).
    Re: Жизнь после OutOfMemory ?
    От: Cyberax Марс  
    Дата: 21.02.08 17:11
    Оценка: +1
    Здравствуйте, leokom, Вы писали:

    L>Возможно ли какое-то нормальное восстановление программы после возникновения иксепшна OutOfMemoryError (который как известно наследует Error)?

    L>Имеет ли смысл
    L>try {
    L>}
    L>catch (OutOfMemoryError ex) {
    L>// hope that everything will be OK? OR
    L>// try to recover in some way?
    L>}
    Тут уже наговорили достаточно много Такая конструкция имеет смысл. НО! Надо понимать что ты делаешь.

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

    К примеру, у нас есть пул обработчиков и менеджер, который раскидывает запросы по этому пулу. Имеет смысл такую конструкцию поставить в том месте, где делается делегирование вызова в пул. И в обработчике поставить немедленную очистку пула и кэшей (если они есть), а потом явный вызов System.gc(). Просто так вызывать GC не стоит, а вот после действий по освобождению памяти — вполне бы и можно.

    Тут хороший принцип есть — лучше позволить системе упасть, а потом правильно восстановиться после сбоя, чем при состоянии сбоя пытаться его маскировать.
    Sapienti sat!
    Re[6]: Жизнь после OutOfMemory ?
    От: Andrei N.Sobchuck Украина www.smalltalk.ru
    Дата: 21.02.08 17:30
    Оценка:
    Здравствуйте, Blazkowicz, Вы писали:
    B>Есть мнение, что при определенных настройках (Parallel GC?) и очень быстром заполнении памяти, можно вызвать OEM ещё до того как GC успеет освободить память, остановить все потоки, или увеличить хип. Сам не сталкивался, всё никак нет времени опробовать.

    Даже больше. При определённых GC (Concurrent GC) можно никогда не получить OOM хотя памяти не будет и приложение при этом не будет работать вообще. Например, исчерпывается N Гб, при этом автоматом запускается полный блокирующий сборщик. Сборка длится несколько минут. И чуток памяти таки освобождается. Приложение потом работает несколько десятков секунд и опять полная сборка на M минут. OOM нету, но приложение почти перманентно в блокированом состоянии.
    Я ненавижу Hibernate!
    Я ненавижу Hibernate
    Автор: Andrei N.Sobchuck
    Дата: 08.01.08
    !
    Re[7]: Жизнь после OutOfMemory ?
    От: Cyberax Марс  
    Дата: 21.02.08 17:46
    Оценка:
    Здравствуйте, Andrei N.Sobchuck, Вы писали:

    ANS>Даже больше. При определённых GC (Concurrent GC) можно никогда не получить OOM хотя памяти не будет и приложение при этом не будет работать вообще. Например, исчерпывается N Гб, при этом автоматом запускается полный блокирующий сборщик. Сборка длится несколько минут. И чуток памяти таки освобождается. Приложение потом работает несколько десятков секунд и опять полная сборка на M минут. OOM нету, но приложение почти перманентно в блокированом состоянии.

    Это можно пофиксить — в 1.5 появилась настройка выброса OOM, если GC занимает более N% процессорного времени.
    Sapienti sat!
    Re[7]: Жизнь после OutOfMemory ?
    От: sss1024 http://microforms.mobile-mir.com/
    Дата: 21.02.08 19:12
    Оценка: :)
    ANS>Я ненавижу Hibernate!

    а я презираю
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.