繁体   English   中英

静态方法的Java内存模型

[英]Java memory model for static methods

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

当我开始学习Java(我确实了解JVM和垃圾收集器)时,我对静态方法感到很开心。 根据我的理解,一个类的所有实例都会在堆中创建,然后再清理。 但是,对于静态方法,不需要类的实例。

因此,可以请一个人解释一下非静态方法和静态方法在内存模型上的区别。 它们是否都位于内存的文本部分。 或者我完全搞砸了。

谢谢

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

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

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

对。 但是所有方法都是类定义的一部分,并且在加载类时一起加载。 即使您从未创建类的实例,所有实例方法的代码也将加载到堆内存中。


然后,将JIT编译为本地代码:使用Hotspot,将常用方法的字节码进一步编译为本地机器代码。 这样的结果确实会在堆之外的某个地方进入本机内存,并且只会在实际使用的方法(静态或非静态)中发生。

您了解到类的所有实例都在堆中创建...

并非完全正确,所有类都被编译为目标字节代码,否则JVM没有任何执行。 实例和静态方法都生成相同的对象字节代码。 甚至非静态类也只生成其目标字节代码的单个版本。 所有实例类都有自己的指针,指向它们在字节代码的单个副本中执行的位置。 真正的区别在于类的数据成员。 非静态类的每个实例必须具有所有非静态数据成员(变量)的自己的副本,但是静态数据成员在内存中仅具有单个副本,因为类的静态数据成员由的所有实例共享。该类是静态的还是非静态的。

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

非静态类在内存中仍然只有其目标代码的一个副本,只有非静态数据为每个实例在内存中获取一个副本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM