JVM 简介

发布于 更新于
本文目录
  1. JVM简介
  2. 概述
  3. 类加载器(Class Loader)
  4. 类加载器
  5. 方法区
  6. 堆
  7. 栈
  8. 程序计数器
  9. 本地方法栈
  10. 本地接口

技术文章测试开发

有多种JVM,如Hot Spot、Dalvik和ART(Android)、Microsoft JVM等,可通过java –version查看,现在通常使用的是Hot Spot

JVM简介

概述

  • 有多种JVM,如Hot Spot、Dalvik和ART(Android)、Microsoft JVM等,可通过java –version查看,现在通常使用的是Hot Spot

  • .java的源代码通过编译成字节码后,会通过的类加载器加载进,然后执行,进行数据处理等操作(如下图,图来自网络)

    图片1.png

类加载器(Class Loader)

  • 负责将.class文件的字节码内容加载到内存,并将内容转换成方法区中的运行时数据结构

  • 只负责加载,是否可运行,由执行引擎决定

  • 类加载器按加载顺序由高到低分为4种:

    • BootstrapClassLoader,根加载器,虚拟机自带,用于加载$JAVA_HOME/jre/lib/rt.jar包内的class文件,rt.jar是Java基础类库,包含Java运行环境所需的基础类,由C++实现

    • ExtClassLoader ,拓展类加载器,虚拟机自带的加载器,用于加载$JAVA_HOME/jre/lib/ext/**.jar目录下的class文件

    • AppClassLoader ,应用程序类加载器,虚拟机自带的加载器,用于加载当前应用的classpath的所有类,也就是我们自己写的那些Java代码

    • 自定义加载器,可以通过继承Java.lang.ClassLoader抽象类自定义一个类加载器,多用于大型项目的版本冲突处理、热加载、字节码加密

  • 双亲委派机制,保证优先加载基础类库;任何类的加载,都会先委托父类寻找指定的类加载器加载,形成一个链条,只有当链条中的某个类没有找到类加载器,才会让链条中的子层次中去寻找这一层次的类加载器;如此,可避免自定义的类会污染自带的基础类库

    图片2.png

类加载器

  • (图片来自网络)

    图片3.png

方法区

  • 所有线程共享的一个运行时内存区域

  • 可以理解为一种规范,不同的JVM实现有不同实现

  • 存储了已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等

堆

  • 一个JVM进程有且只有一个堆,所有线程共享

  • 主要包含

    • 新生代(Yong Generation),包括伊甸园区(Eden Space)和幸存者区(Survivor0和Survivor1)

    • 老年代(Old Generation)

    • 元空间(Meta Space)

    • 堆大小可以在启动JVM时通过-Xms、Xmx等参数进行配置

    • 垃圾回收机制(Garbage Collection)是针对新生代和老年代的堆内存空间进行回收

  • 所有的非基本数据类型对象都活在堆中

栈

  • 每个线程会创建一个栈,生命周期与线程一致,属于线程私有

  • 主要用于保存局部变量、对象引用、操作数栈、动态链接和返回地址等

  • 遵守FILO(First-In/Last-Out)规则,有入栈(Push)和出栈(Pop)操作

  • 可在JVM启动时通过-Xss配置容量,超出容量时会抛出StackOverflowError异常

  • Linux下的JVM默认大小一般是1024KB

程序计数器

  • 每个线程有一个程序计数器,是线程私有

  • 起到一个指针的作用,指向方法区中的方法字节码,存储当前线程的下一条指令地址

  • 主要是解决CPU分时在不同的线程间切换,返回线程时,知道从什么地方继续执行

本地方法栈

  • 用于管理本地接口的调用

本地接口

  • 用于融合不同编程语言代码为Java所用,如C/C++

来源:testingpai

继续阅读