据说Java在内存处理方面比C更安全。 在 C 语言中,通过访问无效指针很容易导致分段错误。现在我想知道java代码是否也会导致分段错误。 有人可以给我举个例子吗?
通常在普通的Java程序中,您不会遇到此问题。 但是,是的,如果您使用类似sun.misc.Unsafe
的东西,可能会导致分段错误。但这就是为什么Unsafe
被称为Unsafe
.通常您不必使用它,因此您的代码中不会出现此问题。
欲了解更多信息: sun.misc.unsafe 记录在哪里?
基于分段错误报告的错误sun.misc.Unsafe
https://github.com/eclipse/openj9/issues/4153
这里有一个如何测试的示例:
import java.lang.reflect.Field;
import sun.misc.Unsafe;
public class MainClass {
public static void main(String[] args)
throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
Unsafe unsafe = (Unsafe) theUnsafe.get(null);
long ten = 10;
byte size = 1;
long mem = unsafe.allocateMemory(size);
//Put here the wrong address!!!
unsafe.putAddress(1, ten);
//With this will work:
//unsafe.putAddress(mem, ten);
long readValue = unsafe.getAddress(mem);
System.out.println("result: " + readValue);
}
}
当我在 Ubuntu 18.04 上执行时,我得到以下输出:A fatal error has been detected by the Java Runtime Environment:
SIGSEGV (0xb) at pc=0x00007f05bdf04d27, pid=4145, tid=4147
JRE version: OpenJDK Runtime Environment (10.0.2+13) (build 10.0.2+13-Ubuntu-1ubuntu0.18.04.4)
在 Windows 上,我认为它将是具有致命错误描述的类似输出。
祝大家好运!
Java语言规范和 Java 虚拟机规范都没有提到分段错误是 Java 程序或 JVM 的行为。这是因为"分段错误"是系统特定的事情(特定于Unix操作系统),而Java意味着可移植的。这些规范也没有将分段错误之类的内容作为允许的行为。此外,Java字节代码的指定语义没有类似于C或C++的"未定义行为"。因此,JVM规范不允许纯Java代码导致分段错误。
如果一个纯Java程序导致了分段错误,那么这将表明JVM本身存在错误。Linux 上的 JVM 是否有可能导致分段错误的错误?答案是肯定的。但是在这种情况下,说Java代码导致了分段错误是正确的吗?我认为不是;我会说"JVM中的错误"导致了分段错误。
所以你的问题的答案是,学究,没有。
Java也可以调用"本机代码"(实际上意味着C代码)。该 C 代码可能存在错误,因此它执行具有未定义行为的操作,因此随后导致分段错误。同样,从学究的角度来看,Java 代码没有导致分段错误;我会说"本机代码中的错误"导致了分段错误。
Java有一个用于执行本机代码(JNI)的接口。这样就可以调用用 C 语言编写的代码,从而使分段错误成为可能。
JVM代码本身中的错误可能会导致分段错误,但这种情况相当罕见。
使用纯Java,没有。该语言旨在仅允许指向有效地址或 null 的引用。在后者之后,你会得到一个NullPointerException。