Здравствуйте, korvin_, Вы писали: _>Это возможно только если под этот твой процесс сохранениня стейта уже была выделена вся необходимая для его работы память, что в языках с GC практически невозможно сделать
Это ещё почему? Сразу выделяем всё на старте. _>соответственно твоё "сделать что-то полезное" точно так же наткнётся на ООМ.
Не обязательно.
_>Это в теории, на практике -- нет. Даже в С/C++ и прочих языках с "ручным" контролем памяти что-то сделать сложно. Поэтому приходит OOM-Killer
OOM-Killer — это следствие криворукой архитектуры линукса. Программы под винду пишутся на тех же С/С++, но при этом там нет (и не нужно) никакого OOM-Killer.
_>Поэтому на практике, что можно сделать: упасть. Гипервизор/оркерстратор перезапустит ноду/сервис/под/контейнер, а мы будем изучать логи, метрики, дампы, и по результату, либо добавим больше памяти, либо изменим параметры масштабирования, либо починим утечку, либо оптимизируем код.
Это очень, очень дорогостоящая процедура. Даже если удалось обойтись без обращения к разработчикам за починкой — всё равно: добавление памяти и перезапуск стоят дней простоя.
Не, я понимаю, что самый простой способ — это просто надеяться. Перезапускаем — может на этот раз карта ляжет так, что упавший процесс успеет отработать до того, как процесс с утечкой сожрёт всю память. _>Так и что бы это дало? Как его использовать? Напиши пример.
Повторюсь: пример зависит от области деятельности и от того, где именно вылетел OOM. Если я получил OOM при создании шестибайтового объекта — да, скорее всего продолжать вообще смысла нет, и можно просто перезапускать весь контейнер или даже всю ноду. А если я пытаюсь выделить буфер размером в 100М, то шанс велик, что после вылета ООМ у меня всё ещё ~50М свободно. И можно заняться чем-то другим, не столь прожорливым к памяти. Или попробовать выделить буфер вдвое меньше. Ну, как пример — сортируем файл интов размером в 100гб. Понятно, что нужно делать сортировку слиянием; и понятно, что чем больше размер чанка, тем быстрее мы закончим. Но это не означает, что неудача выделения чанка в 10G — это катастрофа и нужно делать паник. Можно и 100мб кусками его сортировать — просто это займёт больше времени.
_>Так Optional -- это другой тип по отношению к int.
Ну, так и Expr | OOM — это другой тип по отношению к Expr. _>Теперь, сам Optional же тоже требует памяти, значит Optional<Optional<T>>, и для него тоже нужна память, Optional<Optional<Optional<T>>>, и так далее.
Нет, зачем?
1. В хорошей системе типов Optional Optional == Optional.
2. Независимо от этого, new может всегда резервировать память под sizeof(optional)+sizeof(T), и возвращать none невзирая на то, кому из них не хватило места
4. Независимо от этого, вычислительная модель может быть построена на ref-типах (см. Java), и тогда Optional<T> вообще не требует никаких накладных расходов. Это ровно тот же "ссылка на T", только в отличие от "обычной" ссылки, эта может принимать значение none.
_>Так вот в Haskell/Ocaml и т.п. у нас нет new T, у нас сразу T, как 1, 2, true, false, "foo", "bar". Сразу значение.
Ну, это же иллюзия. Значения всё равно как-то конструируются. Иначе бы любая программа на Haskell была бы просто константой.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.