需要解释为什么会发生 EXCEPTION_ACCESS_VIOLATION
您好,我知道我将要显示的这个错误无法通过代码修复。我只是想知道它为什么以及如何引起的,我也知道它是由于 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
Hi I know that this error which I'm going to show can't be fixed through code. I just want to know why and how is it caused and I also know its due to JVM trying to access address space of another program.
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Tanenbaum 的《现代操作系统》一书,可在此处在线获取:
http:// /lovingod.host.sk/tanenbaum/Unix-Linux-Windows.html
深入讨论该主题。 (第 4 章是内存管理,第 4.8 章是内存分段)。简而言之:
如果您的 PC 上的多个程序可以互相访问内存,那将是非常糟糕的。实际上,即使在一个程序中,即使在一个线程中,您也有多个内存区域,并且这些区域不能相互影响。通常,一个进程至少有一个称为“堆栈”的内存区域和一个称为“堆”的区域(通常每个进程每个线程都有一个堆+一个堆栈。可能有更多的段,但这取决于实现,并且不此处的解释很重要)。在堆栈上,保存了函数的参数和局部变量等内容。堆上保存的是编译器在编译时无法确定其大小和生命周期的变量(这在 Java 中是您使用“new”运算符的所有内容。示例:
在此示例中是两个 String 对象:(由“foo”和“hi”)。这两个对象都在堆上(您知道这一点,因为在某些时候两个字符串都是使用“new”分配的。在这个示例中,3 个值都在堆栈上。这就是值。重要的是要认识到“hi”和“foo”并不直接包含字符串,而是包含一些 id 来告诉它们位于可以找到的堆上。 (这用 java 解释起来并不容易,因为 java 抽象了很多。在 C 中,“hi”和“foo”将是一个指针,它实际上只是一个整数,代表堆中实际值所在的地址。 。
您可能会问自己为什么会有堆栈和堆。不幸的是,解释超出了这个答案的范围 阅读我链接的书;-)。简而言之,堆栈和堆的管理方式不同,并且出于优化原因而进行分离。
栈和堆的大小是有限的。 (在 Linux 上执行 ulimit -a ,您将获得一个列表,其中包括“数据段大小”(堆)和“堆栈大小”(是的...堆栈 :-))。)。
堆栈是一种只会增长的东西。就像一个数组,如果添加越来越多的数据,它就会变得越来越大。最终你会耗尽空间。在这种情况下,您最终可能会写入不再属于您的内存区域。那将是非常糟糕的。因此,操作系统会注意到这一点,并在发生这种情况时停止程序。在 Linux 上,您会遇到“分段错误”,而在 Windows 上,您会遇到“访问冲突”。
在其他语言(例如 C)中,您需要手动管理内存。一个微小的错误很容易导致你不小心写入一些不属于你的空间。在 Java 中,您拥有“自动内存管理”,这意味着 JVM 会为您完成所有这些工作。您不需要关心,这会减轻您作为开发人员的负担(通常是这样。我敢打赌,有人会不同意“负载”部分;-))。这意味着 java.util.Drawing 应该不可能产生分段错误。不幸的是,JVM 并不完美。有时它会出现错误和搞砸。然后你就得到了你所得到的。
The book "modern operating systems" from Tanenbaum, which is available online here:
http://lovingod.host.sk/tanenbaum/Unix-Linux-Windows.html
Covers the topic in depth. (Chapter 4 is in Memory Management and Chapter 4.8 is on Memory segmentation). The short version:
It would be very bad if several programs on your PC could access each other's memory. Actually even within one program, even in one thread you have multiple areas of memory that must not influence one other. Usually a process has at least one memory area called the "stack" and one area called the "heap" (commonly every process has one heap + one stack per thread. There MAY be more segments, but this is implementation dependent and it does not matter for the explanation here). On the stack things like you function's arguments and your local variables are saved. On the heap are variables saved that's size and lifetime cannot be determined by the compiler at compile time (that would be in Java everything that you use the "new"-Operator on. Example:
in this example are two String objects: (referenced by "foo" and "hi"). Both these objects are on the heap (you know this, because at some point both Strings were allocated using "new". And in this example 3 values are on the stack. This would be the value of "myInt", "hi" and "foo". It is important to realize that "hi" and "foo" don't really contain Strings directly, but instead they contain some id that tells them were on the heap they can find the String. (This is not as easy to explain using java because java abstracts a lot. In C "hi" and "foo" would be a Pointer which is actually just an integer which represents the address in the heap where the actual value is stored).
You might ask yourself why there is a stack and a heap anyway. Why not put everything in the same place. Explaining that unfortunately exceeds the scope of this answer. Read the book I linked ;-). The short version is that stack and heap are differently managed and the separation is done for reasons of optimization.
The size of stack and heap are limited. (On Linux execute
ulimit -a
and you'll get a list including "data seg size" (heap) and "stack size" (yeah... stack :-)).).The stack is something that just grows. Like an array that gets bigger and bigger if you append more and more data. Eventually you run out of space. In this case you may end up writing in the memory area that does not belong to you anymore. And that would be extremely bad. So the operating systems notices that and stops the program if that happens. On Linux you get a "Segmenation fault" and on Windows you get an "Access violation".
In other languages like in C, you need to manage your memory manually. A tiny error can easily cause you to accidentally write into some space that does not belong to you. In Java you have "automatic memory management" which means that the JVM does all this for you. You don't need to care and that takes loads from your shoulders as a developer (it usually does. I bet there are people out there who would disagree about the "loads" part ;-)). This means that it /should/ be impossible to produce segmentation faults with java. Unfortunatelly the JVM is not perfect. Sometimes it has bugs and screws up. And then you get what you got.