【问题标题】:need explanation on why does EXCEPTION_ACCESS_VIOLATION occur需要解释为什么会发生 EXCEPTION_ACCESS_VIOLATION
【发布时间】:2011-06-21 06:09:28
【问题描述】:

您好,我知道我要展示的这个错误无法通过代码修复。我只是想知道它为什么以及如何造成的,我也知道它是由于 JVM 试图访问另一个程序的地址空间。

 A fatal error has been detected by the Java Runtime Environment:

  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x6dcd422a, pid=4024, tid=3900

 JRE version: 6.0_14-b08
 Java VM: Java HotSpot(TM) Server VM (14.0-b16 mixed mode windows-x86 )
 Problematic frame:
 V  [jvm.dll+0x17422a]

An error report file with more information is saved as:
C:\PServer\server\bin\hs_err_pid4024.log

If you would like to submit a bug report, please visit:
http://java.sun.com/webapps/bugreport/crash.jsp

【问题讨论】:

  • 这看起来像是 JVM 中的错误!您应该填写错误报告。 :-) 这可能是由内存损坏或错误的指针读取引起的,而不是试图读取另一个程序的内存。
  • 您想了解一般访问违规的背景吗?内存分割等等?还是您只想知道这是由错误引起的?
  • 您是否尝试过 Java 6 update 23,从那时起修复了很多错误。您是否使用任何本机库,因为它们会触发此类错误?
  • @yankee 是的,我想了解更多关于内存分段和访问冲突的信息,如果您有任何好的来源,请提供
  • 您应该尝试更新您的 JVM,重新启动您的机器,看看这是否会消失。

标签: memory-management jvm segmentation-fault access-violation


【解决方案1】:

Tanenbaum 的“现代操作系统”一书,可在此处在线获取:

http://lovingod.host.sk/tanenbaum/Unix-Linux-Windows.html

深入探讨主题。 (第 4 章是内存管理,第 4.8 章是内存分段)。简短版:

如果您的 PC 上的多个程序可以访问彼此的内存,那将是非常糟糕的。实际上,即使在一个程序中,即使在一个线程中,您也有多个不能相互影响的内存区域。通常一个进程至少有一个称为“堆栈”的内存区域和一个称为“堆”的区域(通常每个进程都有一个堆 + 每个线程一个堆栈。可能有更多段,但这取决于实现,它不这里的解释很重要)。在堆栈上,诸如函数参数和局部变量之类的东西都被保存了。在堆上保存的变量的大小和生命周期无法由编译器在编译时确定(这将是在 Java 中您使用“new”-Operator 的所有内容。示例:

public void bar(String hi, int myInt)
{
  String foo = new String("foobar");
}

在这个例子中是两个字符串对象:(由“foo”和“hi”引用)。这两个对象都在堆上(你知道这一点,因为在某些时候两个字符串都是使用“new”分配的。在这个例子中,堆栈上有 3 个值。这将是“myInt”、“hi”和“foo”。重要的是要意识到“hi”和“foo”并不真正直接包含字符串,而是包含一些 id,告诉他们在堆上他们可以找到字符串。(这并不容易使用 java 来解释,因为 java 抽象了很多。在 C 中,“hi”和“foo”将是一个指针,它实际上只是一个整数,表示存储实际值的堆中的地址)。

您可能会问自己,为什么会有堆栈和堆。为什么不把所有东西都放在同一个地方。不幸的是,解释这超出了这个答案的范围。阅读我链接的书;-)。简短的版本是堆栈和堆的管理方式不同,并且出于优化的原因进行了分离。

栈和堆的大小是有限的。 (在 Linux 上执行ulimit -a,你会得到一个列表,包括“数据段大小”(堆)和“堆栈大小”(是的......堆栈:-))。

堆栈是不断增长的。就像一个数组,如果你添加越来越多的数据,它会变得越来越大。最终你的空间用完了。在这种情况下,您最终可能会写入不再属于您的内存区域。那将是非常糟糕的。因此,操作系统会注意到这一点并在发生这种情况时停止程序。在 Linux 上会出现“分段错误”,在 Windows 上会出现“访问冲突”。

在 C 等其他语言中,您需要手动管理内存。一个微小的错误很容易导致您不小心写入一些不属于您的空间。在 Java 中,您有“自动内存管理”,这意味着 JVM 会为您完成所有这些工作。你不需要关心,作为开发人员,这会减轻你的负担(通常是这样。我敢打赌,有些人会不同意“负载”部分;-))。这意味着它/应该/不可能用 java 产生分段错误。不幸的是,JVM 并不完美。有时它有错误和搞砸了。然后你就会得到你所得到的。

【讨论】:

  • 我想要一些关于该错误可能存在于 JVM 中的位置的信息
  • 主要是垃圾收集器,但无论如何感谢您的详细描述 :P :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多