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方法的时候,程序计数器没有值,因为本地方法不是基于字节码来实现的.
- 虚拟机栈
- 符合栈的特性:先进后出
- 栈帧 - 方法级别的概念,简单来说,方法执行之前栈帧入栈,方法执行完毕,栈帧出栈。
- 栈顶的元素通常称为当前栈帧,里面与之相关的方法称之为当前方法.
- 本地方法栈 - 和虚拟机栈大体类似,但处理的对象不同,本地方法栈处理的是本地方法
- 没有栈帧的概念
- 程序计数器
内存的回收
一个消费者资源使用完了,就需要回收,以便给其他消费者使用。