有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java中的jvm,原语静态变量和静态函数存储在哪里?

public Class A {
    public static String s = "s";
    public static int i = 0;
    public int j = 1;
    public static String getStaticString() {
        int k = 2;
        return s;
    }
    public String getString() {
        int l = 3;
        return "something";
    }
}

Java中,静态变量存储在Perm生成的Heap Segment中,原始局部变量存储在Stack Segment中。 那么ijkl存储在哪里呢?函数getString()存储在哪里


共 (1) 个答案

  1. # 1 楼答案

    这些是实现细节,如果不先阅读并理解其源代码,我们无法确定每个实现都做了什么。就我的知识和经验而言,最合理的假设(对于桌面JVM)是:

    • si是静态变量。静态变量可能是在永久生成的堆上分配的
    • j存储在类A的实例中。类实例可能存在于堆栈上(如果对引用的转义分析可以证明引用具有自动存储语义,并且它们足够小),也可能存在于堆上(如果没有执行转义分析,或者转义分析不确定,或者实例对于堆栈来说太大)
    • k是一个具有自动存储语义的局部变量,因此它应该位于堆栈上。它在输入其包含方法(getStaticString)时分配,在退出其包含方法时解除分配
    • lk具有相同的语义。它的包含方法(getString)不是静态的,这一事实与此无关
    • getString(以及任何其他用户代码,无论其语言属性为静态、非静态等)有两种表示:
      • 其元数据和字节码(AOT编译)是其包含类的类数据的一部分。它在内存中的生存期可能与加载/卸载与该代码相关的类有关,但与该类的任何特定实例无关。换句话说,不是每次创建实例时都“创建”非静态方法
      • 它的编译代码(JIT编译)应该永久存在于单独的内存段中(JIT编译器非托管堆的一部分,写入并标记为可执行),与Java对象的生存期无关