Java之黑暗森林 - JVM

一直以来,JVM是Java开发者进阶过程必然要遇到的一块知识点。JVM离绝大多数开发者的实际工作还是比较远的,让人感觉是一个华而不实的东西。或者说有某一类群体,学习JVM就是为了面试,而且是以机械背诵的方式来学习JVM的,这都已经背离了学习一个知识的初衷.

  • 什么是JVM
  • JVM主要解决了哪些问题?
  • JVM点滴

什么是JVM

JVM是一种将高级语言转位机器码的一种工具,目前支持的语言有Java, Clojure, Kotlin, Scala, Groovy.
当从整体上讨论JVM的时候,有两种角度

  • JVM规范
  • JVM实现

在Java的世界里, JVM主要干了两件事(本文以下的讨论都以Java为基础)

  • 将Java文件转为Class文件
  • 将Class文件转为机器码

这两件事描述起来很简单,但从实践角度来说,有很多的细节和技巧,根据我前面提到过的“又快又好”的指标,JVM的目标是如何又快又好的干这两件事.

JVM主要解决了哪些问题?

JVM要解决Java开发过程中遇到的所有问题,比如泛型,异常,基本类型等等,根据二八法则,这里我只讨论一些大的问题,其余琐碎的问题以后单独再聊.

内存的分配

这个问题是个通用的问题,可以简单的描述为:如何将有限的资源合理的分配给各种各样的消费者?或者这个问题接近于现实中的情况:如何将土地和财富分配给社会各阶层的人?

所以内存分配的第一个问题,就是要搞清楚: Java里面占用内存资源的有哪几类要素?如图所示

  • 线程共享
      • 存放new出来的对象
      • 数组
    • 方法区
      • 类信息
        • class文件常量池
      • 静态变量
      • 常量信息
  • 线程不共享
    • 程序计数器
      • 程序计数器是记录的字节码的地址信息。每个线程都有自己的程序计数器,当线程的CPU时间片耗尽挂起之后,需要记录字节码的执行位置,当再次获取到时间片之后,可以从上次的位置继续执行。这个功能是必要的,好比我们看完书的一段章节之后,会将这一页折一下或者用笔做个标注.
      • 执行Native方法的时候,程序计数器没有值,因为本地方法不是基于字节码来实现的.
    • 虚拟机栈
      • 符合栈的特性:先进后出
      • 栈帧 - 方法级别的概念,简单来说,方法执行之前栈帧入栈,方法执行完毕,栈帧出栈。
      • 栈顶的元素通常称为当前栈帧,里面与之相关的方法称之为当前方法.
    • 本地方法栈 - 和虚拟机栈大体类似,但处理的对象不同,本地方法栈处理的是本地方法
      • 没有栈帧的概念

内存的回收

一个消费者资源使用完了,就需要回收,以便给其他消费者使用。

类文件是如何加载的

JVM 点滴