用于静态方法的Java内存模型

我来自C语言的操作系统和背景,当编译代码的时候,世界很简单。 需要处理和理解堆栈,堆文本部分等

当我开始学习Java(我知道关于JVM和垃圾回收器)时,我被静态方法所吸引。 根据我的理解,一个类的所有实例都是在堆中创build的,然后进行清理。 但是,对于静态方法,您不需要该类的实例。

所以,有人可以解释非静态方法和静态方法在内存模型中有何不同。 它们都驻留在内存的文本部分。 或者我搞砸了一切。

谢谢

Solutions Collecting From Web of "用于静态方法的Java内存模型"

在Java中,类(包括它们的方法,静态和实例)的字节码是堆的一部分(通常在长寿命对象的特殊“永久生成”部分)。

类也可以被垃圾收集,但是这通常不会发生太多(只有当类从非系统类加载器加载,并且整个类加载器变得过时时,例如当Web应用程序被卸载时)。

但是,对于静态方法,您不需要该类的实例。

对。 但是所有方法都是类定义的一部分,并且在加载类时加载到一起。 即使你永远不会创建一个类的实例,所有实例方法的代码也会被加载到堆内存中。


然后JIT编译为本地代码:使用Hotspot,经常使用的方法的字节码被进一步编译为本地机器代码。 这样做的结果确实发生在堆外的某个地方,而这只发生在实际使用的方法上(静态的或者没有的)。

你理解一个类的所有实例都是在堆中创建的

不完全正确,所有的类都被编译成对象字节码,否则JVM没有任何可执行的东西。 实例和静态方法都生成相同的对象字节码。 即使非静态类也只生成一个单一版本的对象字节码。 所有的实例类都有自己的指针,指向它们的执行单元的字节码。 真正的区别在于班级的数据成员。 非静态类的每个实例都必须拥有自己的所有非静态数据成员(变量)副本,但是静态数据成员只能在内存中拥有一个副本,因为一个类的静态数据成员被所有的那个类是静态的还是非静态的。

静态类或非静态类的静态数据成员在内存中都有一个自己的副本。

一个非静态类在内存中仍然只有一个对象代码的副本,它只是非静态数据在每个实例的内存中获取一个副本。