我不明白为什么Box::new
不返回Option
或Result
。
由于内存不是无限的,或者其他情况可能发生,因此分配可能会失败; 在这种情况下会发生什么行为? 我找不到任何相关信息。
我不明白为什么Box::new
不返回Option
或Result
。
由于内存不是无限的,或者其他情况可能发生,因此分配可能会失败; 在这种情况下会发生什么行为? 我找不到任何相关信息。
更一般的形式是内存不足时应该怎么办?
处理OOM有许多困难:
第一个问题是检测它。今天许多操作系统默认使用交换空间。在这种情况下,您的进程实际上在OOM出现之前就已经遇到了麻烦,因为开始使用交换空间会显着减慢进程速度。其他操作系统将在更高的进程需要更多内存时(OOM killer)杀死低优先级进程,或者承诺更多内存,希望它不会被使用或将在必要时可用(过度承诺),等等...
第二个问题是恢复。在进程级别上,唯一恢复的方法是释放内存……同时不分配任何内存。这并不像听起来那么容易,例如,并没有保证惊慌和展开不需要分配内存(例如,如果不小心地存储恐慌消息,则可能会进行分配)。这就是为什么当前的rustc运行时默认中止在OOM上。
第三个问题是语言集成:内存分配无处不在。任何使用Box
、Vec
、String
等的操作……因此,如果你避免了恐慌路线,而是使用Result
路线,你需要调整几乎所有的变异方法签名来解决这种失败,这将在所有接口中传播。
Box::try_new()
?)的方式会更好。”请为他翻译成通俗易懂的中文。 - Matthieu M.fn try_alloc<T, F: FnOnce() ->T>(f: F) -> Option<T>
的方式来解决? - red75primevm.overcommit_memory=2
,这会导致内核更愿意在您用尽内存时告诉您。https://serverfault.com/questions/606185/how-does-vm-overcommit-memory-work#606193 - Kent FredricBox::new
),还要考虑它对语言人性化的影响。如果我们使用Return
机制处理内存分配错误,那么这些错误将几乎无处不在地开始浮出水面。即使该方法当前未在堆上分配任何内存,将来也可能会这样做。突然间一个简单的实现更改就会被卡住,因为你必须改变API,而语义版本控制意味着一个重大发布。所有这些都只为了一个小好处,因为在交换和内存杀手存在的情况下,内存耗尽处理并不是非常可靠或有用的(通常你应该在出现内存耗尽错误之前停止分配内存)。对于来自2021年的人来说,Linus与你有相同的担忧。
我确实认为"运行时故障恐慌"是一个根本性问题。
希望通过Rust团队的努力解决这个问题。
https://github.com/rust-lang/rust/pull/84266
catch_unwind
,以便之后可以继续接受新的请求。 - Peter Hall