JVM
一、JVM是什么?
JVM是Java Virtual Machine(java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机及功能来实现的。
二、JVM 内存模型
JVM内存模型指的就是运行时数据区域,叫法比较多,其实说的就是一个东西啦,如下图。
线程共享
- Java堆:
java堆是java虚拟机所管理的内存中最大的一块。Java堆是被所用线程共享的一块内存区域,在虚拟机启动时创建。存放对象实例。
- 方法区:
与java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机记载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
线程私有
- 程序计数器:
是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。我理解的就是假设当前你执行一个方法的代码行。
- 本地方法栈:
与虚拟机栈所发挥的作用非常相似,它们之间的区别不过是虚拟机栈为虚拟机执行java方法(字节码)服务,而本地方法栈则为虚拟机使用的Native方法服务。
- JVM栈:
描述的是java方法执行的内存模型:每个方法在执行的同时都会创建一个栈针用于存储局部变量、操作数栈、动态链接、方法出口等信息。每个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。
三、JVM垃圾回收
3.1GC算法
3.3.1标记清除算法
缺点:
效率不高
产生大量的内存碎片
内存区域分散
3.3.2 复制算法
不足:
浪费内存
适合存活率低的
3.3.3标记整理算法
让存活对象向一端移动
不足:
效率低
3.3.4分代收集算法
分为新生代和老年代,新生代采用复制算法,老年代采用标记清理和标记整理算法。
总结:
效率:复制算法>标记整理算法>标记清除算法
内存整齐度:复制算法=标记整理算法>标记清除算法
内存利用率:标记整理算法=标记清除算法>复制算法
3.2垃圾收集器
Serial
parNew
parallel Scavenge
Serial Old
parallel Old
CMS:用于大堆区域,堆内存分隔,并发回收。
- 初始标记 Initial mark:标记GC Roots能够关联到的对象。stop-the-world。
- 并发标记 Concurrent mark:GC Roots tracing,此时业务线程仍在运行。
- 重新标记 remark:重新标记处理并发标记过程中因为用户程序同时运行而导致标记产生变动的对象的标记记录。stop-the-world。
- 并发清除 Concurrent sweep:清除无用对象。
G1:多线程扫描,标记需要回收的实例,清除。
四、类加载机制
虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的java类型。
类加载时机
对于类加载过程的第一个阶段,加载?java虚拟机规范中并没有进行强制约束,可以交给JVM的具体实现来自由把握。但是对于初始化阶段,jvm规定了有且只有5种情况必须立即对类进行“初始化”。
五、类加载过程
加载
获取定义此类的二进制字节流——将静态存储结构转换为方法区的运行时数据结构——生成有一个java.lang.class对象,作为方法区访问接口。
验证
为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危及虚拟机本身的安全。保证安全
准备
为类变量分配内存,并设置类变量初始值的阶段。
解析
将常量池内的符号引用替换为直接引用。
初始化
类加载的最后一步,真正执行类中定义的java程序代码。
类加载器
双亲委派模式
双亲委派模型的工作过程:如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求时,子加载器才会尝试自己去加载。
六、java内存模型
java内存模型并不是JVM内存模型哦,不要搞混了啊。
java内存模型的主要目标,定义程序中各个变量的访问规则。java线程之间的通信由java内存模型(JMM)控制。
所有变量的存储都在主内存,每条线程都有自己的工作内存,线程的工作内存保存了该线程使用到的变量的主内存副本拷贝,线程对变量的所有操作必须在工作内存完成,而不能直接读取主内存中的变量,不同的线程无法直接访问对方工作内存中的变量,线程间变量的传递需要通过主内存来完成。
七、JVM调优
JVM调优,到底调的是什么?通常也会被面试官问到,调的是Java堆。Java堆,上面也讲到了,根据自己的理解应该可以说出个一二三了。调优实战
总结导图
一起学习吧