说一下 JVM 的主要组成部分?及其作用?
主要有四部分组成:
1.类加载器(ClassLoader)
2.运行时数据区(Runtime Data Area)
3.执行引擎(Execution Engine)
4.本地库接口(Native Interface)
5.本地方法库
作用:
首先通过类加载器(ClassLoader)会把Java代码转换成字节码。
运行时数据区再把字节码加载到内存中而字节码文件只是JVM的一套指令集规范,并不能直接交给底层操作系统去执行。
因此需要特定的命令解析器执行引擎,将字节码翻译成底层系统指令。
再交由CPU去执行,而这个过程中需要调用其他语言的本地库接口来实现整个程序的功能。
JVM 运行时数据区?
在上图中可以看到JVM运行数据区有五部分组成,不同虚拟机的运行时数据区可能略微有所不同,但都会遵从Java虚拟机规范,下面来介绍每一个部分的含义:
程序计数器(Program Counter Register): 当前线程所执行的字节码的行号指示器,字节码解析器的工作是通过改变这个计数器的值,来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能,都需要依赖这个计数器来完成;
Java虚拟机栈(Java Virtual Machine Stacks): 用于存储局部变量表、操作数栈、动态链接、方法出口等信息;
本地方法栈(Native Method Stack): 与虚拟机栈的作用是一样的,只不过虚拟机栈是服务 Java 方法的,而本地方法栈是为虚拟机调用 Native 方法服务的;
Java 堆(Java Heap): Java 虚拟机中内存最大的一块,是被所有线程共享的,几乎所有的对象实例都在这里分配内存;
方法区(Methed Area): 用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。
类装载的执行过程?
类装载分为以下 5 个步骤:
- 加载:根据查找路径找到相应的 class 文件然后导入;
- 检查:检查加载的 class 文件的正确性;
- 准备:给类中的静态变量分配内存空间;
- 解析:虚拟机将常量池中的符号引用替换成直接引用的过程。符号引用就理解为一个标示,而在直接引用直接指向内存中的地址;
- 初始化:对静态变量和静态代码块执行初始化工作。
JVM 有哪些垃圾回收算法?
1.标记-清除算法:标记无用对象,然后进行清除回收。缺点:效率不高,无法清除垃圾碎片。
2.标记-整理算法:标记无用对象,让所有存活的对象都向一端移动,然后直接清除掉端边界以外的内存。
3.复制算法:按照容量划分二个大小相等的内存区域,当一块用完的时候将活着的对象复制到另一块上,然后再把已使用的内存空间一次清理掉。缺点:内存使用率不高,只有原来的一半。
4.分代算法:根据对象存活周期的不同将内存划分为几块,一般是新生代和老年代,新生代基本采用复制算法,老年代采用标记整理算法。
JVM 核心优化策略
1、 JVM 内存优化的第一个问题,取消掉伸缩区,让 total=max;CMS 问题,频繁的 CMS 会导致性能下降;伊甸园区、存活区、老年代的关系要说明白,JDK1.8 之后取消了永久代,而使用元空间代替。
2、如果你的内存过大要使用G1收集器来进行收集;
3、在Tomcat里面由于其使用基于JVM,所以需要设置一个“JAVA_OPTS”指令,可以将全部的内存供tomcat使用(公认的最大可用内存为全部内存的四分之一,默认的total内存为全部内存的64分之1)。