JVM 快速入门

文章目录

    • JVM简介
      • 什么是JVM?
      • 什么是虚拟机?
      • JVM的作用
      • JVM的特点
    • JVM的位置
    • JVM 的结构
    • 类加载器
    • 双亲委派机制
    • 沙箱安全机制
    • native 关键字
    • 程序计数器
    • 方法区
      • 新生区
      • 老年区
      • 元空间
      • IDEA 中设置 JVM 的大小
    • 垃圾回收机制
      • 复制算法
      • 标记清除法
      • 标记整理法

JVM简介

什么是JVM?

JVM是Java虚拟机(Java Virtual Machine)的简称。之所以被叫做虚拟机,是因为它是一个抽象化的计算机,在其内部有完整的硬件架构(寄存器,堆栈,指令系统等)。

简单来说,Java虚拟机就是一台执行Java字节码的虚拟计算机

什么是虚拟机?

定义: 虚拟机就是一台虚拟的计算机。它是一款软件,可以模拟一系列虚拟计算机指令。

虚拟机可以被分为系统虚拟机程序虚拟机两种。
JVM 快速入门_第1张图片

JVM的作用

Java虚拟机是二进制字节码的运行环境,负责装载字节码到其内部,解释/编译为对应平台(Linux,Mac,Windows等)上的机器指令执行。

JVM的特点

  • 平台无关性
  • 一次编译,到处运行
  • 自动内存管理
  • 自动垃圾回收

JVM的位置

前面说到,虚拟机是一款模拟虚拟计算机指令的软件。所以它本质上是一款软件,运行在操作系统之上。
JVM 快速入门_第2张图片

JVM 的结构

JVM 的结构可由下图来简单表示:

JVM 快速入门_第3张图片

Java 内存优化主要集中在堆区,方法区是特殊的堆区。

类加载器

类加载器(ClassLoader)用于将字节码文件加载到 JVM 中去运行

JVM 中提供了三层 ClassLoader:

  1. Bootstrap classLoader:引导类加载器,主要用于加载 Java 的核心类库。
  2. ExtClassLoader:扩展类加载器,用于加载 jre/lib/ext 目录下的一些扩展的 jar 包。
  3. AppclassLoader:系统类加载器,用于加载应用程序中的类。

双亲委派机制

双亲委派机制是 JVM 加载 .class 的机制。当加载一个类时,系统类加载器向上委托给扩展类加载器,扩展类加载器向上委托给引导类加载器。如果引导类加载器中包含这个类,则成功加载。否则向下交给扩展类加载器去加载,扩展类加载器加载不了,就会交由系统类加载器去加载。

JVM 快速入门_第4张图片

双亲委派的优点:(1)避免类重复加载,一旦一个类被父加载器加载后,就不会被子类加载器加载 (2)保护程序安全,防止核心文件被篡改

沙箱安全机制

沙箱是计算机安全领域的一种安全机制,为运行的程序提供隔离的环境。假如 JVM 是一个大的盒子,如果我直接在里面运行一段未知的程序,可能对 JVM 内部的其他程序产生不利的影响。于是,我们可以在 JVM 中建一个小的盒子 (沙箱),让它在这个小盒子中运行。

那如果沙箱中的代码需要访问操作系统和本地资源,该如何保证安全呢?沙箱安全机制给不同的沙箱提供了不同的权限,根据权限来调用操作系统和本地资源。例如,核心类有最高的权限,远程代码有较低的权限。

native 关键字

native 是本地的意思,当方法被 native关键字修饰,表示 Java 的作用范围已经达不到了,会去调用其他语言的库。执行到被 native 修饰的方法后会进入本地方法栈,调用 JNI (Java Native Interface)来操作其他编程语言。

本地方法栈:用于登记 native 方法,在执行引擎执行时加载本地方法库

JNI: 本地方法接口,通过该接口来调用其他语言的类库

Java 使用 native 关键字是为了扩展 Java 的使用,可以在 Java 中使用其他编程语言,进而使其能立足。

程序计数器

每个线程都有一个程序计数器,是线程私有的。它是一个指针,指向方法区中的字节码,告诉执行引擎现在执行到哪一条指令了。

方法区

方法区被所有线程共享,所有字段和方法字节码,以及一些特殊方法,如构造函数,接口代码也在此定义。简单来说,所有定义的方法的信息都保存在该区域,此区域为共享区域。

静态变量、常量、类对象(构造方法、接口定义)运行时的常量池存在方法区中,但是变量实例存在堆内存中

栈是一种后进先出的数据结构。栈主管程序的运行,生命周期与线程同步

线程结束,栈内存也就被释放,所以对栈来说,不存在垃圾回收。

栈中存储的内容有:

  • 八种基本数据类型
  • 堆中对象的引用

JVM 快速入门_第5张图片

堆中用于存储对象的实例。栈是线程级别的,而堆在虚拟机中仅有一个。

堆的内存可以继续细分为:新生区、老年区和元空间。新生区又可被细分为伊甸园区、幸存 0 区和幸存 1 区。

JVM 快速入门_第6张图片

新生区

伊甸园区是对象生成的地方,当伊甸园区内存满的时候,会触发一次轻量级的GC,没有被清理掉的对象会被送到幸存区。当新生区满后,会触发重 GC,重 GC 后存活的对象会被送至老年区。此外,在没有经过设置的情况下,新生区经历过 15 次轻 GC 的对象会被送至老年区。

老年区

老年区用于存储新生区中经历重 GC 或达到轻 GC 阈值次数后仍旧存活的对象。

元空间

元空间常驻内存,存储的是 Java 运行时的一些环境或类信息。

IDEA 中设置 JVM 的大小

在项目构建处,双击 Edit Configurations

JVM 快速入门_第7张图片

在弹出的页面中,设置虚拟机的大小
JVM 快速入门_第8张图片
-Xms8m -Xmx8m -XX:+PrintGCDetails-Xms、-Xmx 用来设置初始化内存分配大小和最大分配内存,-XX:+PrintGCDetails 用来打印 GC 的详细信息。

垃圾回收机制

垃圾回收主要集中在伊甸园区和老年区

垃圾回收的类型包括轻 GC 和 重 GC,轻 GC 只清理新生区,而 重 GC 是全局 GC。

GC 的常用算法包括复制算法、标记清除法和标记整理法。

复制算法

这里我们将幸存者 0 区 和幸存者 1 区称为 from 区和 to 区。当伊甸园区满后,会触发一次轻 GC,存活的对象进入 to 区,然后将 from 区中已有的对象复制到 to 区中;最后将 from 区清空并交换 from 区和 to 区的位置。

这种方法的好处是不会存在内存碎片,且时间复杂度低,缺点是因为要一直维持一个空的 to 区,造成了资源的浪费。

标记清除法

标记清除法包括两步,首先扫描一遍,标记需要清除的元素,然后再扫描一遍清除对象。

这种方法的好处不会造成资源的浪费,但有较高的时间复杂度,且会产生内存碎片。

标记整理法

标记整理法在标记清除法的基础上,通过移动对象的方式避免了内存碎片的产生。

相比标记清除法,该算法的时间复杂度更高,但不会存在内存碎片。

你可能感兴趣的:(Java,java,开发语言)