我来自C的操作系统和背景,在这里,代码编译时世界很简单。需要处理和理解堆栈、堆文本部分等。
当我开始学习Java(我确实了解JVM和垃圾收集器)时,我对静态方法很感兴趣。根据我的理解,类的所有实例都会在堆中创建,然后进行清理。但是,对于静态方法,不需要类的实例。
那么,有谁能解释一下非静态方法和静态方法在内存模型中的区别吗?它们是否都驻留在内存的文本部分。否则我就把事情搞砸了。
谢谢
发布于 2015-01-23 00:08:08
在Java中,类的字节码(包括它们的方法,包括静态的和实例的)是堆的一部分(通常在一个用于长寿命对象的特殊“永久生成”部分)。
类也可以被垃圾收集,但是这种情况通常不会发生太多(只有当类从非系统类加载器加载,并且整个类加载器变得过时时,例如当web应用程序被卸载时)。
但是,对于静态方法,不需要类的实例。
正确的。但是,所有方法都是类定义的一部分,并在加载类时一起加载。即使您从未创建类的实例,所有实例方法的代码也将加载到堆内存中。
然后是将JIT编译成本机代码:使用Hotspot,常用方法的字节码将进一步编译成本机代码。这样做的结果确实会在堆之外的某个地方进入本机内存,而且这种情况只会发生在实际使用的方法(静态或非静态)上。
发布于 2015-01-23 01:27:46
您的理解是,类的所有实例都是在堆中创建的。
不完全正确,所有类都被编译成对象字节代码,否则JVM就没有什么可执行的了。实例和静态方法都生成相同的对象字节代码。即使是非静态类也只能生成其对象字节代码的单个版本。所有实例类都有自己的指针,指向它们在字节码的单个副本中的执行位置。真正的区别在于类的数据成员。非静态类的每个实例都必须有自己的所有非静态数据成员(变量)的副本,但是静态数据成员在内存中只有一个副本,因为该类的静态数据成员由该类的所有实例静态或非静态共享。
静态类或非静态类的静态数据成员在内存中都有它们自己的一个副本。
非静态类在内存中仍然只有其对象代码的一个副本,只有非静态数据才能为每个实例在内存中获得副本。
https://stackoverflow.com/questions/28100825
复制相似问题