Жизнь после OutOfMemory ?
От: leokom Украина http://neformatc.blogspot.com
Дата: 21.02.08 07:35
Оценка:
Возможно ли какое-то нормальное восстановление программы после возникновения иксепшна OutOfMemoryError (который как известно наследует Error)?
Имеет ли смысл

try {
}
catch (OutOfMemoryError ex) {
// hope that everything will be OK? OR
// try to recover in some way?

}
Re: Жизнь после OutOfMemory ?
От: sss1024 http://microforms.mobile-mir.com/
Дата: 21.02.08 07:49
Оценка:
Здравствуйте, leokom, Вы писали:

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

L>Имеет ли смысл

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

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


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

L>>Имеет ли смысл

S>да.


А какую разумную процедуру восстановления можно предложить? Виртуальная машина не находится ли после этого еррора уже в таком состоянии с которого ее "не поднять"?
Re: Жизнь после OutOfMemory ?
От: denis.zhdanov Россия http://denis-zhdanov.blogspot.com/
Дата: 21.02.08 07:53
Оценка: 1 (1) +1
Здравствуйте, leokom, Вы писали:

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

L>Имеет ли смысл

L>...


В общем случае не имеет, потому что OOME может возникнуть в любом месте кода (например, при банальном toString()).
http://denis-zhdanov.blogspot.com
Re[3]: Жизнь после OutOfMemory ?
От: sss1024 http://microforms.mobile-mir.com/
Дата: 21.02.08 08:03
Оценка: -3
L>А какую разумную процедуру восстановления можно предложить? Виртуальная машина не находится ли после этого еррора уже в таком состоянии с которого ее "не поднять"?

а что поднимать-то. Просто память кончилась

Runtime.gc()
Thread.sleep(1000)

дальше удалить что-нибудь ненужное или по обстоятельствам.
Re[4]: Жизнь после OutOfMemory ?
От: denis.zhdanov Россия http://denis-zhdanov.blogspot.com/
Дата: 21.02.08 08:14
Оценка: 4 (3) +1
Здравствуйте, sss1024, Вы писали:

S>а что поднимать-то. Просто память кончилась


S>Runtime.gc()

S>Thread.sleep(1000)

S>дальше удалить что-нибудь ненужное или по обстоятельствам.


-1
Спецификация гарантирует, что перед тем, как бросить out of memory, jvm сделает все возможное для того, чтобы попытаться очистить память (запустит full collection, соберет soft references).
http://denis-zhdanov.blogspot.com
Re[5]: Жизнь после OutOfMemory ?
От: sss1024 http://microforms.mobile-mir.com/
Дата: 21.02.08 08:15
Оценка:
DZ>-1
DZ>Спецификация гарантирует, что перед тем, как бросить out of memory, jvm сделает все возможное для того, чтобы попытаться очистить память (запустит full collection, соберет soft references).

и что
Re[6]: Жизнь после OutOfMemory ?
От: dshe  
Дата: 21.02.08 08:31
Оценка: 1 (1)
Здравствуйте, sss1024, Вы писали:

DZ>>-1

DZ>>Спецификация гарантирует, что перед тем, как бросить out of memory, jvm сделает все возможное для того, чтобы попытаться очистить память (запустит full collection, соберет soft references).

S>и что


то что повторный запуск сборщика мусора и ожидание 1 секунду настолько редко помогает при OOM, что рассчитывать не него не стоит.
--
Дмитро
Re[7]: Жизнь после OutOfMemory ?
От: sss1024 http://microforms.mobile-mir.com/
Дата: 21.02.08 08:40
Оценка: -4
S>>и что

D>то что повторный запуск сборщика мусора и ожидание 1 секунду настолько редко помогает при OOM, что рассчитывать не него не стоит.


ну запусти после удаления ненужных объектов. Аутофмемори вполне штатная ситуация
Re: Жизнь после OutOfMemory ?
От: jitm  
Дата: 21.02.08 10:12
Оценка: 1 (1)
Здравствуйте, leokom, Вы писали:

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

L>Имеет ли смысл
Тут тебе человек написал что имеет, я сначала с этим утверждением был не согласен но полез в спецификацию и вот что нарыл :

11.5.2.2 Virtual Machine Errors
A Java Virtual Machine throws an object that is an instance of a subclass of the class VirtualMachineError when an internal error or resource limitation prevents it from implementing the semantics of the Java Language. This language specification and the Java Virtual Machine Specification define the following virtual machine errors:

InternalError: An internal error has occurred in a Java Virtual Machine, because of a fault in the software implementing the virtual machine, a fault in the underlying host system software, or a fault in the hardware. This error is delivered asynchronously when it is detected, and may occur at any point in a Java program.
OutOfMemoryError: A Java Virtual Machine has run out of either virtual or physical memory, and the automatic storage manager wasn't able to reclaim enough memory to satisfy an object creation request.
StackOverflowError: A Java Virtual Machine has run out of stack space for a thread, typically because the thread is doing an unbounded number of recursive invocations due to a fault in the executing program.
UnknownError: An exception or error has occurred but, for some reason, a Java Virtual Machine is unable to report the actual exception or error.
A sophisticated Java program may be designed to handle OutOfMemoryError and attempt to recover from it, perhaps by carefully dropping references to objects.

We are exploring enhancements to Java to simplify handling of out-of-memory conditions. One possibility would be to support automatic suspension of a thread which encounters an OutOfMemoryError and allow another thread to handle the error situation. Such a technique might also permit a Java program to recover from a StackOverflowError if this overflow does not result from a nonterminating recursion. Suggestions for other approaches are welcomed.

Re[4]: Жизнь после OutOfMemory ?
От: Blazkowicz Россия  
Дата: 21.02.08 10:39
Оценка:
Здравствуйте, sss1024, Вы писали:

S>а что поднимать-то. Просто память кончилась

S>Runtime.gc()
S>Thread.sleep(1000)
S>дальше удалить что-нибудь ненужное или по обстоятельствам.

Да уж, вирус с sql.ru расползается с невероятной скоростью. Меня там совсем не давно пытались убедить в том что это отличное решение. Уважаемый, где вы этой дряни набрались?
Re[2]: Жизнь после OutOfMemory ?
От: leokom Украина http://neformatc.blogspot.com
Дата: 21.02.08 10:39
Оценка:
Здравствуйте, jitm, Вы писали:

J>

J>We are exploring enhancements to Java to simplify handling of out-of-memory conditions. One possibility would be to support automatic suspension of a thread which encounters an OutOfMemoryError and allow another thread to handle the error situation. Such a technique might also permit a Java program to recover from a StackOverflowError if this overflow does not result from a nonterminating recursion. Suggestions for other approaches are welcomed.


То есть, получается разработчики джавы еще сами толком не знают что в этом случае делать и ищут красивые выходы из ситуации. (про поток-обработчик).

Но так и не ясно что делать с существующими вирт. машинами джавы... Так как улучшения про которые они тут пишут еще только "в проекте"

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

J> Тут тебе человек написал что имеет, я сначала с этим утверждением был не согласен но полез в спецификацию и вот что нарыл :

J>

J>We are exploring enhancements to Java to simplify handling of out-of-memory conditions. One possibility would be to support automatic suspension of a thread which encounters an OutOfMemoryError and allow another thread to handle the error situation. Such a technique might also permit a Java program to recover from a StackOverflowError if this overflow does not result from a nonterminating recursion. Suggestions for other approaches are welcomed.


С некоторых пор за объемами памяти можно наблюдать через JMX. Эта функциональность позволяет навесить специальный слушатель, и когда размер свободной памяти будет приближатся к критическому, то выполнять нужные действия в контексте своего приложения.
Re[2]: Жизнь после OutOfMemory ?
От: denis.zhdanov Россия http://denis-zhdanov.blogspot.com/
Дата: 21.02.08 10:41
Оценка:
Здравствуйте, jitm, Вы писали:

J> Тут тебе человек написал что имеет, я сначала с этим утверждением был не согласен но полез в спецификацию и вот что нарыл :


J>...
J>OutOfMemoryError: A Java Virtual Machine has run out of either virtual or physical memory, and the automatic storage manager wasn't able to reclaim enough memory to satisfy an object creation request.
J>...

J>We are exploring enhancements to Java to simplify handling of out-of-memory conditions. One possibility would be to support automatic suspension of a thread which encounters an OutOfMemoryError and allow another thread to handle the error situation. Such a technique might also permit a Java program to recover from a StackOverflowError if this overflow does not result from a nonterminating recursion. Suggestions for other approaches are welcomed.


Ключевые моменты:

  1. ОМЕ может случиться в любой точке программы, где создается новый объект. Невозможно заранее предсказать где;
  2. Можно предположить существование программы, которая создает объекты в одном/нескольких строго определенных местах. При этом она использует алгоритм наподобие такого, который производит вычисления с точностью, не выше заданной (могущей быть большой), но позволяющий вернуть значение, посчитанное с меньшей точностью. Тогда можно реализовать это так, что поступают новые данные, начинаются вычисления, как только получаем OME, зануляем ссылки на данные с результатами промежуточных вычислений, просим о полной сборке и возвращаем то, что успели посчитать. Не думаю, что процент подобных программ от общего числа приложений равен хотя бы единице;
  3. В будущем планируется ввести более удобные механизмы по восстановлению от OME, которые позволят использовать это в более широком круге задач;
http://denis-zhdanov.blogspot.com
Re[5]: Жизнь после OutOfMemory ?
От: leokom Украина http://neformatc.blogspot.com
Дата: 21.02.08 10:43
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

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


S>>а что поднимать-то. Просто память кончилась

S>>Runtime.gc()
S>>Thread.sleep(1000)
S>>дальше удалить что-нибудь ненужное или по обстоятельствам.

B>Да уж, вирус с sql.ru расползается с невероятной скоростью. Меня там совсем не давно пытались убедить в том что это отличное решение. Уважаемый, где вы этой дряни набрались?



Видимо это "решение" действительно не будет работать так как вирт. машина перед броском этого иксепшна сама попыталась "собрать мусор"... Вопрос в том имеет ли смысл ловить такой иксепшн и например пытаться ручками за-null-ить какие-то возможно ненужные объекты, а потом "попросить" вирт. машину снова "поубирать" (только попросить так как гарантий выполнения сборщика она не дает). Или после OutOfMemory работа вирт. машины вообще неопределенна, и лучше всего закрыть аппликейшн?
Re[5]: Жизнь после OutOfMemory ?
От: Blazkowicz Россия  
Дата: 21.02.08 10:44
Оценка:
Здравствуйте, denis.zhdanov, Вы писали:

DZ>Спецификация гарантирует, что перед тем, как бросить out of memory, jvm сделает все возможное для того, чтобы попытаться очистить память (запустит full collection, соберет soft references).

Есть мнение, что при определенных настройках (Parallel GC?) и очень быстром заполнении памяти, можно вызвать OEM ещё до того как GC успеет освободить память, остановить все потоки, или увеличить хип. Сам не сталкивался, всё никак нет времени опробовать.
Re[6]: Жизнь после OutOfMemory ?
От: Blazkowicz Россия  
Дата: 21.02.08 10:46
Оценка: 1 (1) +1
Здравствуйте, leokom, Вы писали:

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


Если есть желание поборотся за хип. То безопаснее предотвратить OME, чем его ловить:
http://rsdn.ru/forum/message/2847535.1.aspx
Автор: Blazkowicz
Дата: 21.02.08
Re[6]: Жизнь после OutOfMemory ?
От: denis.zhdanov Россия http://denis-zhdanov.blogspot.com/
Дата: 21.02.08 10:50
Оценка: +2
Здравствуйте, leokom, Вы писали:

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


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

Расскажи лучше о задаче, в качестве возможного решения которой ты рассматриваешь обработку ОМЕ. Я уверен, что можно будет предложить лучшую альтернативу.
http://denis-zhdanov.blogspot.com
Re[3]: Жизнь после OutOfMemory ?
От: jitm  
Дата: 21.02.08 10:53
Оценка:
Здравствуйте, denis.zhdanov, Вы писали:

DZ>Ключевые моменты:


DZ>

    DZ>
  1. ОМЕ может случиться в любой точке программы, где создается новый объект. Невозможно заранее предсказать где;
    Ну это я понимаю прекрасно но автор топика как — то это думает побороть раз задал такой вопрос иначе наше обсуждение просто флейм ...
    DZ>
  2. Можно предположить существование программы, которая создает объекты в одном/нескольких строго определенных местах. При этом она использует алгоритм наподобие такого, который производит вычисления с точностью, не выше заданной (могущей быть большой), но позволяющий вернуть значение, посчитанное с меньшей точностью. Тогда можно реализовать это так, что поступают новые данные, начинаются вычисления, как только получаем OME, зануляем ссылки на данные с результатами промежуточных вычислений, просим о полной сборке и возвращаем то, что успели посчитать. Не думаю, что процент подобных программ от общего числа приложений равен хотя бы единице;

    +1
    Полностью согласен

    DZ>
  3. В будущем планируется ввести более удобные механизмы по восстановлению от OME, которые позволят использовать это в более широком круге задач;
    Ну в принцыпе в спеке написано тоже
    DZ>
Re[3]: Жизнь после OutOfMemory ?
От: jitm  
Дата: 21.02.08 10:58
Оценка:
Здравствуйте, leokom, Вы писали:

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


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


L>То есть, получается разработчики джавы еще сами толком не знают что в этом случае делать и ищут красивые выходы из ситуации. (про поток-обработчик).

Получается что так.
L>Но так и не ясно что делать с существующими вирт. машинами джавы... Так как улучшения про которые они тут пишут еще только "в проекте"
Да, но у меня встречный вопрос если ты хош ловить ООМЕ то ты знаешь де оно происходит ? Если знаешь то может просто не доводить до ООМЕ, как ты на это смотришь ? Если не знаешь то ты либо пишешь так как описал denis.zhdanov либо тебе стало скучно и ты решил поговорить
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!

    а я презираю
    Re[2]: Жизнь после OutOfMemory ?
    От: rsn81 Россия http://rsn81.wordpress.com
    Дата: 22.02.08 04:30
    Оценка:
    Здравствуйте, Cyberax, Вы писали:

    C>Тут хороший принцип есть — лучше позволить системе упасть, а потом правильно восстановиться после сбоя, чем при состоянии сбоя пытаться его маскировать.

    +1, вобщем-то. Странно, что так долго никто не озвучивал эту наиболее важную сторону проблемы.
    Re[3]: Жизнь после OutOfMemory ?
    От: sss1024 http://microforms.mobile-mir.com/
    Дата: 22.02.08 05:55
    Оценка: :)
    Здравствуйте, rsn81, Вы писали:

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


    C>>Тут хороший принцип есть — лучше позволить системе упасть, а потом правильно восстановиться после сбоя, чем при состоянии сбоя пытаться его маскировать.

    R>+1, вобщем-то. Странно, что так долго никто не озвучивал эту наиболее важную сторону проблемы.

    ну да. Когда микрософт ворд падает а потом правильно восстанавливается после сбоя это нормально, он же документ восстанавливает и редактирование не теряется.
    Re[8]: Жизнь после OutOfMemory ?
    От: Andrei N.Sobchuck Украина www.smalltalk.ru
    Дата: 22.02.08 12:25
    Оценка:
    Здравствуйте, Cyberax, Вы писали:

    C>Это можно пофиксить — в 1.5 появилась настройка выброса OOM, если GC занимает более N% процессорного времени.


    Именно опция? Я помню про такую инфу для Throughput Collector:

    if the JVM is spending more than 98% of the total time doing garbage collection and is recovering less than 2% of the heap, it will throw an out-of-memory expection

    Если приложение блокировано 5 мин потом работает 30 сек, то оно работает 10%. А с точки зрения пользователей оно вовсе не работает. Плюс, с одной сборки мусора такую ситуацию определить нельзя. Нужно, как минимум 2.

    В добавок интересна взаимосвязь этой опции с CMS. Когда запускается полная сборка мусора в CMS, то это какой сборщик?
    Я ненавижу Hibernate!
    Я ненавижу Hibernate
    Автор: Andrei N.Sobchuck
    Дата: 08.01.08
    !
    Re[9]: Жизнь после OutOfMemory ?
    От: Blazkowicz Россия  
    Дата: 22.02.08 12:38
    Оценка:
    Здравствуйте, Andrei N.Sobchuck, Вы писали:

    ANS>Если приложение блокировано 5 мин потом работает 30 сек, то оно работает 10%. А с точки зрения пользователей оно вовсе не работает. Плюс, с одной сборки мусора такую ситуацию определить нельзя. Нужно, как минимум 2.


    В более поздней доке
    http://java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html#cms.oom
    Написано только про то что это поведение можно изменить. А вот на счет сконфигурять ничего вроде нет.
    Re[10]: Жизнь после OutOfMemory ?
    От: Andrei N.Sobchuck Украина www.smalltalk.ru
    Дата: 22.02.08 12:47
    Оценка:
    Здравствуйте, Blazkowicz, Вы писали:

    B>В более поздней доке

    B>http://java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html#cms.oom
    B>Написано только про то что это поведение можно изменить. А вот на счет сконфигурять ничего вроде нет.

    Ээ. "Изменить" или "отменить"?
    Я ненавижу Hibernate!
    Я ненавижу Hibernate
    Автор: Andrei N.Sobchuck
    Дата: 08.01.08
    !
    Re[10]: Жизнь после OutOfMemory ?
    От: Andrei N.Sobchuck Украина www.smalltalk.ru
    Дата: 22.02.08 12:49
    Оценка:
    Здравствуйте, Blazkowicz, Вы писали:

    B>В более поздней доке

    B>http://java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html#cms.oom

    Получается, что не факт, что в 1.5 это поведение применимо к CMS сборщику. В любом случае, такую бяку в поведении я видел, а OME нет
    Я ненавижу Hibernate!
    Я ненавижу Hibernate
    Автор: Andrei N.Sobchuck
    Дата: 08.01.08
    !
    Re[11]: Жизнь после OutOfMemory ?
    От: Blazkowicz Россия  
    Дата: 22.02.08 12:52
    Оценка:
    Здравствуйте, Andrei N.Sobchuck, Вы писали:

    ANS>Ээ. "Изменить" или "отменить"?

    Да. Не точно выразился. "Предотвратить".
    Re[9]: Жизнь после OutOfMemory ?
    От: Cyberax Марс  
    Дата: 22.02.08 13:01
    Оценка:
    Здравствуйте, Andrei N.Sobchuck, Вы писали:

    ANS>Если приложение блокировано 5 мин потом работает 30 сек, то оно работает 10%. А с точки зрения пользователей оно вовсе не работает. Плюс, с одной сборки мусора такую ситуацию определить нельзя. Нужно, как минимум 2.

    Этот процент можно крутить, я точно помню.

    ANS>В добавок интересна взаимосвязь этой опции с CMS. Когда запускается полная сборка мусора в CMS, то это какой сборщик?

    AFAIR, если ты запускаешь полную сборку — то это уже не CMS. Для CMS там свои опции.
    Sapienti sat!
    Re[10]: Жизнь после OutOfMemory ?
    От: Andrei N.Sobchuck Украина www.smalltalk.ru
    Дата: 22.02.08 13:09
    Оценка:
    Здравствуйте, Cyberax, Вы писали:

    C>AFAIR, если ты запускаешь полную сборку — то это уже не CMS. Для CMS там свои опции.


    Она сама запускается — concurrent mode failure и вперёд.
    Я ненавижу Hibernate!
    Я ненавижу Hibernate
    Автор: Andrei N.Sobchuck
    Дата: 08.01.08
    !
    Re[11]: Жизнь после OutOfMemory ?
    От: Cyberax Марс  
    Дата: 22.02.08 13:18
    Оценка:
    Здравствуйте, Andrei N.Sobchuck, Вы писали:

    C>>AFAIR, если ты запускаешь полную сборку — то это уже не CMS. Для CMS там свои опции.

    ANS>Она сама запускается — concurrent mode failure и вперёд.
    Это я и имел в виду. Если запускается stop-the-world, то CMS уже сделал всё возможное.
    Sapienti sat!
    Re[3]: Жизнь после OutOfMemory ?
    От: leokom Украина http://neformatc.blogspot.com
    Дата: 25.02.08 07:27
    Оценка:
    Что значит "маскировать сбой"? Если мы пытаемся ловить OutOfMemoryError, который наследует не Exception а Error, мы уже частично маскируем проблему, подменяя обычную работу вирт. машины (которая просто закроет процесс, когда это Error дойдет до верхнего метода и не будет обработан).

    Если позволить системе системе упасть — то ... что же запускать еще один процесс который мониторит не упал ли наш, и если упал — запустить его снова?
    Re[4]: Жизнь после OutOfMemory ?
    От: dshe  
    Дата: 25.02.08 08:20
    Оценка: 4 (4) +2 :)
    Здравствуйте, leokom, Вы писали:

    L>Что значит "маскировать сбой"? Если мы пытаемся ловить OutOfMemoryError, который наследует не Exception а Error, мы уже частично маскируем проблему, подменяя обычную работу вирт. машины (которая просто закроет процесс, когда это Error дойдет до верхнего метода и не будет обработан).


    Ну, при OOM процесс (т.е. VM) не завершается.

    L>Если позволить системе системе упасть — то ... что же запускать еще один процесс который мониторит не упал ли наш, и если упал — запустить его снова?


    Мне кажется, что здесь важно понимать, что подобные исключения (включая NPE, IAE, ...) это симптомы ошибок, но не сами ошибки. И правильной стратегией было бы выяснить причину (при помощи отладчика, профайлера, логов...) и исправить ее (изменить код, возможно конфигурацию и т.п.). А попытка остаться на плаву любой ценой, неважно как: явно перехватив исключение, якобы обработав его; или периодически перезапуская постоянно падающий процесс отдельным скриптом; — на мой взгляд это все равно, что лечить кашель пластырем на рот.
    --
    Дмитро
    Re[5]: Жизнь после OutOfMemory ?
    От: leokom Украина http://neformatc.blogspot.com
    Дата: 25.02.08 09:14
    Оценка:
    Здравствуйте, dshe, Вы писали:

    D>Ну, при OOM процесс (т.е. VM) не завершается.


    Стоп... Я начал сейчас сомневаться в понимании Core Java. Если объект который наследует Throwable не будет перехвачен никем, то насколько я понимаю процесс завершится.

    main() {

    //smth
    throw new OutOfMemoryError(); //- этот иксепшн мог быть сгенерен виртуальной машиной
    //anything
    }

    Тут anything выполнен не будет и ВМ завершит джава-программу и себя. Или я не прав?
    Re[6]: Жизнь после OutOfMemory ?
    От: denis.zhdanov Россия http://denis-zhdanov.blogspot.com/
    Дата: 25.02.08 09:40
    Оценка: 2 (2) +1
    Здравствуйте, leokom, Вы писали:

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


    D>>Ну, при OOM процесс (т.е. VM) не завершается.


    L>Стоп... Я начал сейчас сомневаться в понимании Core Java. Если объект который наследует Throwable не будет перехвачен никем, то насколько я понимаю процесс завершится.


    L>main() {


    L>//smth

    L>throw new OutOfMemoryError(); //- этот иксепшн мог быть сгенерен виртуальной машиной
    L>//anything
    L>}

    L>Тут anything выполнен не будет и ВМ завершит джава-программу и себя. Или я не прав?


    Завершится поток, в котором вылетело необработанное исключение. В твоем примере поток один ==> когда он завершится, весь процесс завершится.
    http://denis-zhdanov.blogspot.com
    Re[4]: Жизнь после OutOfMemory ?
    От: Cyberax Марс  
    Дата: 25.02.08 16:39
    Оценка:
    Здравствуйте, leokom, Вы писали:

    L>Что значит "маскировать сбой"?

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

    L>Если мы пытаемся ловить OutOfMemoryError, который наследует не Exception а Error, мы уже частично маскируем проблему, подменяя обычную работу вирт. машины (которая просто закроет процесс, когда это Error дойдет до верхнего метода и не будет обработан).

    Нет, уже ответили.

    L>Если позволить системе системе упасть — то ... что же запускать еще один процесс который мониторит не упал ли наш, и если упал — запустить его снова?

    От одного OOM оно не умрёт...

    Подоход "перезапустить при падении" — это тоже вариант. Надо только при этом писать так, чтобы восстановление после падения не вызывало других ошибок.
    Sapienti sat!
    Re[6]: Жизнь после OutOfMemory ?
    От: Eugeny__ Украина  
    Дата: 28.02.08 11:09
    Оценка:
    Здравствуйте, leokom, Вы писали:


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


    Если есть потенциально ненужные объекты(причем или много, или крупные по размеру, то есть те, которые действительно занимают значительную область памяти), то не лучше ли ссылаться на них через мягкие ссылки? В таком случае не будет ни OOM, ни геморроя с его отловом.
    Новости очень смешные. Зря вы не смотрите. Как будто за наркоманами подсматриваешь. Только тетка с погодой в завязке.
    There is no such thing as a winnable war.
    Re[6]: Жизнь после OutOfMemory ?
    От: Eugeny__ Украина  
    Дата: 28.02.08 11:10
    Оценка:
    Здравствуйте, Blazkowicz, Вы писали:


    DZ>>Спецификация гарантирует, что перед тем, как бросить out of memory, jvm сделает все возможное для того, чтобы попытаться очистить память (запустит full collection, соберет soft references).

    B>Есть мнение, что при определенных настройках (Parallel GC?) и очень быстром заполнении памяти, можно вызвать OEM ещё до того как GC успеет освободить память, остановить все потоки, или увеличить хип. Сам не сталкивался, всё никак нет времени опробовать.

    На 1.3 с таким сталкивались. В последних версиях — не знаю.
    Новости очень смешные. Зря вы не смотрите. Как будто за наркоманами подсматриваешь. Только тетка с погодой в завязке.
    There is no such thing as a winnable war.
    Re[8]: Жизнь после OutOfMemory ?
    От: Eugeny__ Украина  
    Дата: 28.02.08 12:14
    Оценка:
    Здравствуйте, leokom, Вы писали:

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

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

    А данные какого рода? Возможны 2 варианта:
    1. сервер выдает длинный список данных, каждый элемент которого является законченным(не зависящим от других) объектом, и его можно положить в базу
    2. все десятки мегабайт — один объект, который нужно обрабатывать целиком

    Второй вариант сильно сложнее, и общего решения для него нет, но встречается такое реже.

    А в случае первого — выкидываем DOM, берем SAX. Вычитываем понемногу данные из потока. Как только понимаем, что приняли законченный объект, кидаем его в базу, и забываем, переходя к считыванию дальше. Если такие атомарные объекты невелики, то OOM словить будет сложно.
    Новости очень смешные. Зря вы не смотрите. Как будто за наркоманами подсматриваешь. Только тетка с погодой в завязке.
    There is no such thing as a winnable war.
    Re[8]: Жизнь после OutOfMemory ?
    От: Stormblast http://www.myspace.com/stormblastblack
    Дата: 28.02.08 14:05
    Оценка: :)
    Здравствуйте, leokom, Вы писали:

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

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

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