据说Java在内存处理方面比C更安全。 在C语言中,通过访问无效指针很容易引起分段错误。现在,我想知道java代码是否还会导致分段错误。 有人可以给我一个例子吗?
答案 0 :(得分:3)
通常在普通Java程序中,您不会遇到此问题。
但是可以,如果您使用sun.misc.Unsafe
之类的东西,可能会导致分段错误。但这就是Unsafe
被称为Unsafe
的原因。通常,您不必使用它,因此您的代码中不会出现此问题。
有关更多信息: Where is sun.misc.Unsafe documented?
根据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上,我认为它将是类似的输出,并带有致命错误说明。
祝大家好运!
答案 1 :(得分:2)
Java语言规范和Java虚拟机规范都没有将分段错误提到Java程序或JVM的行为。这是因为"segmentation fault"是系统特定的东西(特定于Unix操作系统),而Java是可移植的。这些规范也没有给出允许的行为类似的分段错误。此外,Java字节码的指定语义不像C或C ++的"undefined behaviour"。因此,JVM规范不允许纯Java代码导致分段错误。
如果纯Java程序导致分段错误,则表明JVM本身存在错误。 Linux上的JVM是否可以存在可能导致分段错误的错误?当然。但是在那种情况下,可以说 Java代码引起了分段错误吗?我觉得不是;我会说“ JVM中的错误”导致了分段错误。
因此,就您的问题而言,答案是否。
Java也可以调用"native code"(实际上是C代码)。该C代码可能存在错误,因此它执行的操作具有未定义的行为,因此会导致分段错误。再一次, Java代码并没有引起分段错误。我会说“本地代码中的错误”导致了分段错误。
答案 2 :(得分:1)
Java具有用于执行本机代码(JNI)的接口。这样就可以调用用C编写的代码,从而可能导致分段错误。
JVM代码本身中的错误会导致分段错误,但是这种情况很少见。
使用纯Java,否。该语言仅允许引用指向有效地址或null的引用。在后者之后,您将获得NullPointerException。