提问人:Raedwald 提问时间:1/4/2012 最后编辑:Matthias BraunRaedwald 更新时间:6/11/2021 访问量:6376
无抛出 VirtualMachineError 保证
No-throw VirtualMachineError guarantees
问:
我是从C++开始学习Java的。在 C++ 世界中,我们关注异常安全,并注意到 mutator 在面对 mutator 本身或它委托给的方法(最小值、强值、不抛出)抛出的异常时,mutator 可以提供不同的保证。实现具有强异常保证的方法需要保证某些基本操作永远不会引发异常。JLS 会声明哪些操作可以抛出哪些类型的异常,但该错误会带来问题。引用 JLS:VirtualMachineError
内部错误或资源限制阻止了 Java 虚拟 机器从实现 Java 编程的语义 语言;在本例中,将抛出 的子类的实例。
VirtualMachineError
JLS 不再说 .“内部错误”意味着 JVM 中的错误,所以我对这种情况不感兴趣:面对 JVM 中的错误,所有的赌注都失败了。但是“资源限制”的情况呢?是否有任何操作可以保证永远不会因资源限制而失败?VirtualMachineError
答:
引用 Java 虚拟机规范:
此规范无法预测内部错误或资源的位置 可能会遇到限制,并且没有确切规定何时 他们可以被报告。因此,任何子类 下面定义的可以在操作期间随时抛出 Java 虚拟机:
VirtualMachineError
因此,在 Java 中,不能对 VirtualMachineError
异常做出任何异常保证。所有例外保证必须符合“......但如果抛出 A,则不会”。这是Java与C++的不同之处之一。VirtualMachineError
这也表明,捕获异常没有多大意义,因为如果抛出异常,则程序处于未定义状态。不幸的是,这包括例外情况。很不幸,因为如果一个程序有几个独立的任务要执行(例如,一个 Web 服务器),如果一个任务因为需要太多内存而失败,我们可能希望继续执行其他任务。VirtualMachineError
OutOfMemoryError
评论
如果是资源限制,首先,不会进行任何操作。这是 VirtualMachineError 完美示例的链接。虚拟机错误
此错误与 OutofMemoryError 不同,此时某些操作可能正在进行中。
评论
我看到你已经回答了你自己的问题,我可以理解为什么这对你来说有点惊讶,因为你来自严格的 C++ 背景。这只是托管内存(虚拟机)计算机的现实,它不仅限于 java。内存可能会耗尽,因为 JVM 受限于它可以使用的堆数量(可在 java 命令行上配置)。
在C++/机器代码世界中,有点类似,但不等价,在尝试对未分配或位于虚拟地址空间之外的内存进行寻址时,您将获得一个GENERAL_PROTECTION_FAULT(如果您使用的是 *NIX,则为 SEGMENTATION_FAULT)。面对这种情况,提供“强异常保证”同样困难,因为原因可能是代码中的错误或完全超出程序的控制范围。
评论
NullPointerException
OutOfMemoryError
new
null
在 Java 中,您可以随时调用 Thread.stop() 或 stop(Throwable)。大多数错误都被认为是非常严重的,除非你真的知道自己在做什么,否则你不应该尝试处理它们。
开发服务器端 Java 应用程序已有 12 年了,我可以说我从未听说过有人担心抛出随机异常。我怀疑这不是您需要担心的 Java 问题。
您能否举例说明为什么您认为需要保证,因为可能有另一种方法可以解决问题?
评论
OutOfMemoryError
OutOfMemoryError
OutOfMemoryError
评论
try { ... } catch (Throwable t) { }