Java验证器和解析器

Bob*_*r02 5 java verification jvm resolution

假设我们有以下定义:

public class Test {

    public static void main(String[] args) {
        System.out.println("------MAIN METHOD------");
        A a = new B();  
        a.a = 3;
        System.out.println(a.a);
    }

}

    public class A {

        int a;

        public void g(){
            System.out.println(a);
        }

    }

public class B extends A {}
Run Code Online (Sandbox Code Playgroud)

现在,假设我们构建上述内容,然后将 B 修改为

public class B {}
Run Code Online (Sandbox Code Playgroud)

并重建 JUST B。当我们关闭验证器时,该方法会打印 3!我知道验证程序没有捕获到这一点,结果在 A 中检查是否存在 sa 字段 a,就是这种情况......但是 B 没有为整数字段 a 分配空间!那么它会写到哪里呢?

Jör*_*ann 4

内存中的java对象被填充并对齐为至少16字节长,因此在仅包含int字段的类中存在一些未使用的空间。如果向 A 添加更多字段,您可能会覆盖其他对象的存储空间,但这也可能不会导致立即崩溃,特别是在这样一个立即退出的短应用程序中。

您可以通过像这样声明类来获得更多乐趣:

public class A {
    int[] a = new int[1];
}

public class B {
    int a = 0x01020304;
}

public class Test {
    public static void main(String[] args) {
        A a = new B();  
        a.a[0] = 3;
        System.out.println(a.a[0]);
    }
}
Run Code Online (Sandbox Code Playgroud)

通过执行此代码的结果java -Xverify:none Test应该会导致如下所示的 JVM 错误,但原则上它应该允许您将任何位置写入 java 进程的内存中:

------MAIN METHOD------
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f9147d69532, pid=14785, tid=140262017775360
#
# JRE version: 6.0_26-b03
# Java VM: Java HotSpot(TM) 64-Bit Server VM (20.1-b02 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# j  Test.main([Ljava/lang/String;)V+17
Run Code Online (Sandbox Code Playgroud)