解读JVM虚拟机

【解读JVM虚拟机】概要点:

  • java虚拟机概述和基本概念
  • 堆、栈、方法区
  • 了解虚拟机参数
  • 垃圾回收概念和算法、及对象的分代转换
  • 垃圾收集器
java虚拟机的原理:
  • 所谓虚拟机 , 就是一台虚拟的机器 。 它是一款软件 , 用来执行一系列虚拟计算机指令 , 大体上虚拟机可以分为系统虚拟机和程序虚拟机 , 大名鼎鼎的Visual Box、VMare就属于系统虚拟机 , 他们完全是对物理计算机的仿真 , 提供了一个可运行完整操作系统的软件平台 。
  • 程序虚拟机典型代表就是Java虚拟机 , 它专门为执行单个计算机程序而设计 , 在java虚拟机中执行的指令我们成为java字节码指令 。 无论是系统虚拟机还是程序虚拟机 , 在上面运行的软件都被限制于虚拟机提供的资源中 。 Java发展至今 , 出现过很多虚拟机 , 最初Sun使用的一款叫Classic的Java虚拟机 , 到现在引用最广泛的是HotSpot虚拟机 , 除了Sun以外 , 还有BEA的JRockit , 目前JRockit和HotSpot都被Oracle收入旗下 , 大有整合的趋势 。
java虚拟机的基本结构
解读JVM虚拟机文章插图
结构概念说明:
  • 类加载子系统:负责从文件系统或者网络中加载Class信息 , 加载的信息 存放在一块称之为方法区的内存空间 。
  • 方法区:就是存放类信息、常量信息、常量池信息、包括字符串字面量和数字常量等 。
  • java堆:在java虚拟机启动的时候建立java堆 , 它是java程序最主要的内存工作区域 , 几乎所有的对象实例都存放到java堆中 , 堆空间是所有线程共享的 。
  • 直接内存:Java的NIO库允许java程序使用直接内存 , 从而提高性能 , 通常直接内存速度会优于java堆 。 读写频繁的场合可能会考虑使用 。
  • 每个虚拟机线程都有一个私有的栈 , 一个线程的java栈在线程创建的时候被创建 , java栈中保存着局部变量、方法参数、同时java的方法调用、返回值等 。
  • 本地方法栈和java栈非常类似 , 最大不同为本地方法栈用于本地方法调用 。 java虚拟机允许java直接调用本地方法(通常使用C编写) 。
  • 垃圾收集系统是java的核心 , 也是必不可少的 , java有一套自己进行垃圾清理的机制 , 开发人员无需手工清理 , 我们稍后详细说明 。
  • PC(Program Counter)寄存器也是每个线程私有的空间 , java虚拟机会为每个线程创建PC寄存器 , 在任意时刻 , 一个java线程总是在执行一个方法 , 这个方法被称为当前方法 , 如果当前方法不是本地方法 , PC寄存器就会执行当前正在被执行的指令 , 如果是本地方法 , 则PC寄存器值为undefined,寄存器存放如当前执行环境指针、程序计数器、操作栈指针、计算的变量指针等信息 。
  • 虚拟机最核心的组件就是执行引擎了 , 它负责执行虚拟机的字节码 。 一般会先进行编译成机器码后执行
堆、栈、方法区概念和联系:
  • 堆解决的是数据存储的问题 , 即数据怎么放、放在哪儿 。 栈解决程序的运行问题 , 即程序如何执行 , 或者说如何处理数据 。
  • 方法区则是辅助堆栈的快永久区(Perm) , 解决堆栈信息的产生 , 是先决条件 。
  • 我们创建一个新的对象 , User:那么User类的一些信息(类信息、静态信息都存在于方法区中) 而User类被实例化出来之后 , 被存储到java堆中 , 一块内存空间 当我们去使用的时候 , 都是使用User对象的引用 , 形如User user = new User(); 这里的user就是存放在java栈中的 , 即User真实对象的一个引用 。

解读JVM虚拟机文章插图
java栈:
  • java栈是一块线程私有的内存空间 , 一个栈 , 一般由三部分组成:局部变量表、操作数栈和帧数据区 。
  • 局部变量表:用于报错函数的参数及局部变量 。 操作数栈:主要保存计算过程的中间结果 , 同时作为计算过程中变量临时的存储空间 。
  • 帧数据区:除了局部变量表和操作数栈以外 , 栈还需要一些数据来支持常量池的解析 , 这里帧数据区保存着访问常量池的指针 , 方便程序访问常量池 。
  • 另外 , 当函数返回或者出现异常时 , 虚拟机必须有一个异常处理表 , 方便发送异常的时候找到异常的代码 , 因此异常处理表也是帧数据区的一部分 。

解读JVM虚拟机文章插图
java方法区: