一、JVM简介
JVM:Java Virtual Machine 的简称,Java 虚拟机,也就是在计算机上再虚拟一个计算机,JVM是一个内存中的虚拟机,所以他的存储也是在内存中,我们写的类,常量,变量,方法都是在内存中。
二、JVM构成
- class Loader 类加载器
类加载器的作用是将.java文件经过javac编译后的.class文件加载到内存中,并由Execution Engine 来执行。 - Execution Engine 执行引擎
执行引擎也叫做解释器(Interpreter),负责解释命令,提交操作系统执行。 - Native Interface 本地接口
Native Interface的作用是融合不同的语言为Java所用。 Runtime Data Area 运行数据区域
我们所有的程序都是加载到这里,然后才开始运行的。- Method Area方法区
方法区时所有线程共享,所有的字段和字节码,以及特殊方法(构造函数,接口代码都在此定义)。简单说,所有定义的方法的信息都保存在该区域,此区域属于共享区间。
静态变量+常量+类信息+运行时常量池都在方法区中,实例变量是在堆内存中。 - Stack 栈
线程创建时创建,其生命周期是和线程同步,线程结束栈内存结束。
基本变量和对象的引用变量都是在栈内存中。 Heap
堆这块区域是JVM中最大的,应用的对象和数据都是存在这个区域,这块区域也是线程共享的,也是 gc 主要的回收区,一个 JVM 实例只存在一个堆类存,堆内存的大小是可以调节的。类加载器读取了类文件后,需要把类、方法、常变量放到堆内存中,以方便执行器执行,堆内存分为三部分:- 新生区
新生区是类诞生成长消亡的区域,一个类在这里产生使用,最后被来垃圾回收。新生区又分为:伊甸区(类的创建)和幸存者区(类的存储和销毁)。
OutOfMemoryError : Java heap space说明类内存不够,导致的原因:
(1)java 虚拟机内存设置不够,可以通过设置-Xms、-Xmx来调整。
(2)代码中产生大量对象,并且没有被垃圾回收(对象被引用) - 养老区:养老区用来存储新生区筛选出来的对象
- 永久存储区:存储jdk自身携带的class,interface,存储的就是运行环境必须的元数据,被装载进来的对象不会被gc回收,只有关闭jvm才会释放内存。
如果出现java.lang.OutOfMemoryError: PermGen space
a. 程序启动需要加载大量的第三方jar包。例如:在一个Tomcat下部署了太多的应用。
b. 大量动态反射生成的类不断被加载,最终导致Perm区被占满。
- 新生区
- Method Area方法区
三、JVM 加载class文件的机制
java中所有的类都需由classLoader类加载到jvm中才能运行,他本身也是一个类,他的主要工作就是把class文件由硬盘读取到内存。在写程序时,基本上不需要考虑加载的过程,因为这些都是隐式加载的。
加载类型:
- 隐式加载 :在程序运行中,碰到通过new生成对象时,隐式调用类加载器加载对应的类到jvm中。
- 显示加载: 通过class.forname()等方法,显式加载需要的类。
四、JVM 原理机制
- 装载和导入class文件
- 连接
- 检查装载class文件的准确性
- 为类的静态变量分配空间
- 初始化静态变量,静态代码块