【Java总结】JVM

279 阅读4分钟

一、Java运行时数据区

  1. 程序计数器:代表当前线程所执行的字节码的信号指示器。可以记录当前线程执行虚拟机字节码指令的地址。
  2. java虚拟机栈:每个方法在执行的时候创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等。
  • 局部变量表存放编译时期就可以知道的各种基本数据类型、对象引用。
  • 如果线程请求栈深度大于虚拟机所允许的深度,抛出StackOverFlowError异常。
  • 如果虚拟机栈扩展无法申请到足够的内存时,抛出OutOfMemoryError异常。
  1. 本地方法栈:与虚拟机栈类似,不过虚拟机栈是为java方法服务,而本地方法栈为Native方法服务。
  2. 堆:虚拟机中内存最大的区域,存放所有对象实例。
  3. 方法区:存储虚拟机加载的类信息,各种常量、静态变量、即时编译器编译后的代码区域等。

image.png

二、对象回收

  1. 对象从生成到回收的过程
  • 对象的创建以及内存分配:通过new关键字执行对象创建并分配内存。
    • 虚拟机遇到new指令时,会检查指令的参数在常量池是否能定位到类的符号引用。没有则进行类加载
    • 类加载完成后,为对象分配内存空间
    • 设置对象,例如对象是哪个类实例、对象哈希码等
    • 填充对象
  • 对象的初始化:通过调用构造函数,完成对象成员的初始化
  • 对象的应用和操作:完成内存的分配和资源的初始化操作,就可以使用这些资源进行一定的操作和应用。
  • 资源清理:应用完对象后,必须对对象访问的资源进行清理。
  • 垃圾回收:内存资源释放由GC负责。
  1. 如何判断对象已死
  • 引用计数算法:为每个对象设置一个引用计数器,每引用一次,计数器+1;当引用失效时,计数器-1,当计数器为0时需要回收(无法解决相互引用问题)
  • 可达性分析:从一个GC根节点出发,向下搜索走过的路径成为引用链,当一个对象不可达时,则证明对象不可用。在java中,可作为GC根节点包括以下几种:虚拟机栈引用的对象,方法区类静态属性引用的对象,本地方法栈引用的对象。

三、垃圾回收算法

  1. 标记-清除算法(Mark-Sweep) 从根节点开始标记所有可达对象,其余没标记的即为垃圾对象,执行清除。但回收后的空间是不连续的。

  2. 复制算法(copying) 将内存分成两块,每次只使用其中一块,垃圾回收时,将标记的对象拷贝到另外一块中,然后完全清除原来使用的那块内存。

  3. 标记-压缩算法(Mark-compact) 适合用于老年代的算法(存活对象多于垃圾对象)。标记后不复制,而是将存活对象压缩到内存的一端,然后清理边界外的所有对象。

四、垃圾回收器

  1. Serial收集器:采用复制算法的新生代收集器,但线程收集器,在进行垃圾收集时,必须暂停其它所有工作线程
  2. ParNew收集器:是Serial收集器的多线程版本。除了使用多线程外,其余行为与Serial收集器完全相同。
  3. Parallel Scavenge收集器:并行的多线程新生代收集器,它也使用复制算法,目标是达到一个可控制的吞吐量(Throughput)。无法与CMS收集器配合使用。
  4. Serial Ol的收集器:是Serial收集器的老年代版本,同样是一个但线程收集器,使用“标记-整理”算法。此收集器的主要意义也是在于给Client模式下的虚拟机使用。在Server模式下,作为CMS收集器的后备预案。
  5. Parallel Old收集器:是Parallel Scavenge收集器的老年代版本,使用多线程和“标记-整理”算法。这个收集器是在JDK 1.6中才开始提供的
  6. CMS(Concurrent Mark Sweep)收集器:是一种以最短回收停顿时间为目标的收集器,使用“标记-清除”算法。
  7. G1(Garbage-First)收集器:面向服务器的垃圾收集器,主要针对配备多颗处理器及大容量内存的机器。
  8. Zgc:(The Z Garbage Collector)JDK11 中推出的一款低延迟垃圾回收器