JVM

来源:互联网 发布:淘宝搜索关键词排行榜 编辑:程序博客网 时间:2024/06/08 18:09

1、类的实例化顺序
http://www.importnew.com/18548.html
java类的加载是由虚拟机来完成的,虚拟机把描述类的Class文件加载到内存,并对数据进行校验,解析和初始化,最终形成能被java虚拟机直接使用的java类型,这就是虚拟机的类加载机制。JVM中用来完成上述功能的具体实现就是类加载器.类加载器读取.class字节码文件将其转换成java.lang.Class类的一个实例.每个实例用来表示一个java类。通过该实例的newInstance()方法可以创建出一个该类的对象。
类的加载,首先会加载静态的东西:静态代码块,静态属性和静态方法,这些是全局的,但是静态的方法会初始化,但是不调用的话是不会执行的初始化完成之后,才会给变量赋值。

① 启动类加载器(BootstrapClassLoader):

这个类加载器负责将<JAVA_HOME>\lib目录下的类库加载到虚拟机内存中,用来加载java的核心库,此类加载器并不继承于java.lang.ClassLoader,不能被java程序直接调用,代码是使用C++编写的是虚拟机自身的一部分.
② 扩展类加载器(ExtendsionClassLoader):
这个类加载器负责加载<JAVA_HOME>\lib\ext目录下的类库,用来加载java的扩展库,开发者可以直接使用这个类加载器.
③ 应用程序类加载器(ApplicationClassLoader):
这个类加载器负责加载用户类路径(CLASSPATH)下的类库,一般我们编写的java类都是由这个类加载器加载,这个类加载器是CLassLoader中的getSystemClassLoader()方法的返回值,所以也称为系统类加载器.一般情况下这就是系统默认的类加载器.除此之外,我们还可以加入自己定义的类加载器,以满足特殊的需求,需要继承java.lang.ClassLoader类.



2、JVM内存
① 堆:用来存储对象本身和数组的(数组的指针在java栈中)。堆是被所有线程共享的,在JVM中只有一个堆。JDK8中的堆内分划分和JDK7是不一样的,JDK7以及之前的版本PermGen Space 是在堆中的,当永久代满了之后会报OutOfMemoryError:PermGen Space 错误。JDK8中永久代就不在堆中了,而是移到了本地内存中,会根据永久代对象的大小动态调整metaSpace区的大小。
② 栈:存放的是一个个的栈帧,每个栈帧包括:局部变量表,操作数栈,运行时常量池的引用,方法返回地址,附加信息。
③ 程序计数器(PC寄存器):保存的是正在执行命令的内存地址。
④ 方法区:它和堆一样是所有线程共享的。存放了一些常量、静态变量、类信息等,可以理解成class文件在内存中的存放位置。方法区 是对 Permanet Generation在JVM规范里定义的标准名称,从Java8开始,方法区被删除,开始使用metaSpace,并且metaSpace不再放在运行时数据区,而是放到了native memory,虽然以后再也看不到OOME:PermGen space 了,但是多了一个OOME:mata space 。

虚拟机中的共划分为三个代:年轻代(Young Generation)、老年代(Old Generation)和持久代(Permanent Generation)。其中持久代主要存放的是Java类的类信息,与垃圾收集要收集的Java对象关系不大。年轻代和年老代的划分是对垃圾收集影响比较大的。

年轻代分三个区。一个Eden区,两个Survivor区(一般而言)