我是 JVM(HotSpot)的新手,并尝试了解它的架构及其工作原理,所以我的问题是所有方法(静态和非静态)都被翻译成字节码吗?当JVM加载类文件时,它是否将所有方法加载到某个地方?喜欢方法区?还是本机方法堆栈?
6 回答
它取决于 JVM 的实现——不同的 JVM 可能会选择以不同的方式处理这个问题(只要它们符合 Java 规范)。所以你没有绝对的保证。
在 Sun/Oracle JVM 中,方法数据被加载到称为“永久代”的特殊内存区域,这是垃圾收集器为诸如类之类的长寿命对象保留的内存区域。
大多数其他“工业级”JVM 可能会做类似的事情。
看:
- https://blogs.oracle.com/jonthecollector/entry/presenting_the_permanent_generation
- java内存池是怎么划分的?
- http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html
附言
这都是非常高级的东西——你绝对不需要知道任何关于这方面的知识来充分利用 Java 和/或 JVM。您通常应该假设 JVM 代表您进行内存管理并且会有效地执行此操作 - 它已经由专家进行了多年的调整。
JVM 的全部意义在于让你从特定平台的实现细节中抽象出来,毕竟......
准确地说,
所有方法(静态和非静态)都将加载到方法区域中。
方法调用、局部变量、中间结果和执行行将存储在 Stack 中。
如果一个方法正在执行,它会在栈顶。一旦执行完成,所有结果都将被删除,如果有任何局部引用变量,它们将被取消。
不管正在执行的方法是什么,方法 Area 都有类信息。它类似于浏览器中的缓存,保存 JVM 所需的信息。
1.) 是否所有方法(静态和非静态)都被翻译成字节码?
- 是的,一个类的所有成员,无论是静态的还是非静态的,都会被翻译成字节码。编译器负责所有这些翻译/编译。
2.)当JVM加载类文件时,它是否将所有方法加载到某个地方?喜欢方法区?还是本机方法堆栈?
- 类的整个字节码(包括方法字节码)被加载到各自的类块中。
- 类块是方法区域内逻辑上分离的内存块,用于存储各自类的类级数据,例如字节码、方法表和静态变量。
- 类级数据与实例无关,即为什么它不存储在堆中类的实例(对象)中。所有对象共享一个类级数据的副本。
- 所以,这个问题的简单答案是“所有类字节码(包括方法的字节码)都加载到方法区”。
- 要了解有关方法领域的更多信息,请访问 https://www.artima.com/insidejvm/ed2/jvm5.html或参考 SCJP/Oracle 学习指南
我通常建议您阅读这篇关于 JVM 基本要素的精彩文章。
https://anturis.com/blog/java-virtual-machine-the-essential-guide/
是的,所有的方法都被翻译成字节码。字节码文件是 jvm 将从中加载的中间文件。
jvm什么时候加载class文件?它会在第一次使用该类时执行此操作——包含以下几种情况:
- 创建类的实例:new 运算符、反射、克隆方法或反序列化。
- Inoking 类的静态方法。
- 使用或评估类或接口的静态变量(最终静态变量除外),因为它们是编译时常量。
- 通过反射调用方法。
- 加载类的子类。它仅适用于接口以外的类。
- jvm 的引导类。例如。包含 main 方法的类。
- 实现接口的类在初始化时不需要初始化接口,但必须加载。
是的,方法被加载到方法区域。换句话说,字节码文件被加载到方法区。
Java进程消耗的内存可以分为Java和Native heap。Java堆是由大小为Xmx的jvm分配的内存部分,用于Java对象分配,其中作为由JNI代码分配的本地内存部分和由本地语言完成的分配。是否所有方法(静态和非静态)都被翻译成字节码?
用 java 编写的代码被转换为字节码以进行访问,而与访问说明符或修饰符无关
当JVM加载类文件时,它是否将所有方法加载到某个地方?像方法区?或本地方法堆栈?
Class(Method) 区域存储每个类的结构,例如运行时常量池、字段和方法数据、方法的代码。