свап - еще 4гб. И того 8гб. Вы говорите, что за "попытку" аллокации 12гб памяти ООМ убьет процесс ? Только за сам факт попытки ?
Я выше писал про vm_overcommit. Может возвратить null при попытке аллокации, и тогда раст сделает abort. Или может дождаться пока процесс реально использует сколько-то памяти и тогда уже придёт OOM killer
Как сделать так что бы abort не сработал, а обработать эту ошибку в программе своим кодом? Если .push не возврашает ошибки ? Только try_reserve ? Или есть еще другие способы ?
Да, пока только try_reserve и vm_overcommit = 2 (но это может сломать запуск процессов, выполняющийся через fork + execcv).
Благодарствую ! Пойду переосмысливать логику обработки ошибок в своих проектах.
Я видел что довольно часто писали свою реализацию: trait VecExt<T> { fn try_push(&mut self, elem: T) -> Result<(), T>; } impl<T> VecExt<T> for Vec<T> { fn try_push(&mut self, elem: T) -> Result<(), T> { if self.try_reserve(self.len() + 1).is_err() { return Err(elem); } self.push(elem); Ok(()) } } fn main() { let mut v = vec![]; v.try_push(1).unwrap(); v.try_push(1).unwrap(); v.try_push(1).unwrap(); } Но не знаю, как такое ведет себя с OOM killer-ом, и в целом слышал что обработка OOM - сложное место с кучей подводных камней
в общем случае никак. Как бы хорошо и аккуратно ты себя не вел, оомкиллер все равно может тебя убить, если выжравший всю память процесс более важен
Согласен. Но я говорил, о случае, когда помять свободная есть, но приложение хочет больше чем есть, и вот в этом случае abort() нежелателен, а нужно обработать ошибку своей процедурой.
Обсуждают сегодня