java类加载机制

来源:互联网 发布:php获取post json数据 编辑:程序博客网 时间:2024/06/07 16:51

最近在重新回顾java基础,对java运行时整个内存运行的机制很好奇,看了一点深入理解java虚拟机 高级特性和最佳实践,觉得整个jvm运行机制还是比较复杂的。待日后有时间再好好深入了解,暂时先在站在理解程序的级别上简述一下。


首先先是运行时的java的内存区域



简单讲一下各个区域

  程序计数器:当前线程所执行的字节码的行号指示器,循环,线程恢复等基础功能依赖这个计数器完成(线程私有,每一个线程都会有自己单独的一个计数器)。

  本地方法栈:与java虚拟机栈相似,不过执行的是native方法。

  方法区(包含运行时常量池):各个线程共享的区域,它用于已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。

  java虚拟机栈:也是线程私有的,生命周期与线程相同  每个方法执行时都会创建一个栈帧(一会儿会详细讲到)结构是栈结构,先进后出。

  java堆:被线程共享 java虚拟机管理的内存中最大的一块,几乎所有的对象实例都在这里分配内存,也是java垃圾收集器主要管理的区域。

  运行时常量池:方法区的一部分 主要存放类的版本,字段,方法,接口等描述信息和常量池。常量池里在类加载后进入运行时常量,里面存放编译期生成的各种字面量和符号引用等。


 

然后就是类的加载过程

  类加载时机通常在

  1.new创建实例时

  2.调用该类的静态方法

  3.Class.forname("");

  .....(当类初始化时,会将他的父类一起初始化)

类的加载整个分为三个部分

 1. 加载  

      类加载器将字节码文件读入内存,并创建一个java.lang.Class对象

 2. 连接

      (1)验证
      (2)准备  

         为类的静态Field分配内存,设置系统默认初始值

      (3)解析

         将常量池中的符号引用替换为直接引用

 3. 初始化(主要是对staticField进行初始化)

1 2

1图的最后i值为3

2图的最后i值为2

根据顺序进行赋值,但1图中static代码块可以操作i变量,2图中不行,static代码块只对i进行赋值。






0 0
原创粉丝点击