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

时间:2014-10-25 15:48:24

标签: 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中,静态变量存储在PermHeap Segment中,原始局部变量存储在Stack Segment中。 那么ijkl存储在哪里?函数getString()存储在哪里?

1 个答案:

答案 0 :(得分:3)

这些是实现细节,我们无法在不首先阅读和理解其源代码的情况下确定每个实现的功能。就我的知识和经验而言,最合理的假设(对于桌面JVM)是​​这样的:

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