Feng.Li's Java See

抓紧时间,大步向前。
随笔 - 95, 文章 - 4, 评论 - 58, 引用 - 0
数据加载中……

JVM使用方法区信息例子

本文是对JVM执行一个Class文件的过程的一个总结。比如,现在我有2个类:
1:Class Lava {
   private int speed = 5;
   void flow() {}
}
2:    Class Volcano {
   public static void main(String [] args) {
    Lava lava =  new Lava ();
    lava.flow()
}
}
下面就是JVM的某个实现执行Class文件的一个过程:

1:JVM找到并读入相应的Class文件 :Volcano.class,然后把导入的二进制数据中提取的类型信息保存到方法区(方法区:保存类型信息的运行时数据区,也就是JVM内存管理体系结构的一个组成)

2:执行保存在方法区的字节码 (执行main()方法的字节码,)在执行时,持有指向Volcano类常量池的一个指针 (常量池:就是一个符号引用 如:Lava lava = new Lava()这句中的Lava就是一个符号引用)

3:JVM只在需要时才装载类(动态连接) 。JVM使用常量池指针找到第一项,发现是"Lava"字符串,检查方法区,发现Lava类并未被装载。


4:开始装载Volcano.class,同样,把读入的二进制数据中的类型信息放到方法区。

5:JVM用一个直接指向方法区Lava类数据的指针来替换常量池的第一项,也就是原先的“Lava”字符串。 这个过程就是所谓的:“常量池解析”---符号引用替换为直接引用。

6:JVM准备为新的Lava对象分配内存。分配对象当然需要类型信息,此时,用刚才替换的那个指针,也就是替换“Lava”字符串的那个指针(此时,这个指针指向方法区Lava类的数据)来访问Lava的类型信息(这个信息刚放到方法区)。找出其中记录的这样一个信息:需要分配多少内存。

7:确定内存要多大以后,在堆上分配内存,并初始化变量,包括超类的变量()。

8:把新生成的Lava对象引用压到Java栈中。到此,完成Lava lava = new Lava(); speed初始化为0。

9:通过此时生成的Lava引用,把speed 初始化为正确的值 :5

10: 通过这个引用调用Flow()。

以上为我以一个例子来说明JVM 的一个实现执行Class的流程,欢迎大家阅读和提出意见.

posted on 2006-12-14 12:05 小锋 阅读(2143) 评论(4)  编辑  收藏 所属分类: J2SE

评论

# re: JVM使用方法区信息例子  回复  更多评论   

《深入Java虚拟机》这本书真不错,讲的很清楚啊。。。
2007-08-23 22:44 | carrincha

# re: JVM使用方法区信息例子  回复  更多评论   

个人感觉第8和9需要修改一下
改为“通过Lava的默认构造函数将Lava对象压入栈中,并完成初试化”
应该说明下lava被压入的原因 这样才清晰 你说呢?
2008-10-23 11:11 | wangc

# re: JVM使用方法区信息例子  回复  更多评论   

关于speed的两次初始化 你有何依据 能不能说来听听:)
2008-10-23 11:14 | wangc

# re: JVM使用方法区信息例子  回复  更多评论   

帖子不能修改 这个很头疼
2008-10-24 09:22 | wangc

只有注册用户登录后才能发表评论。


网站导航: