当前位置: 首页 > article >正文

深入了解JVM:Java程序背后的核心原理

JVM常见原理

JVM(Java Virtual Machine)是Java程序的运行环境,它是一个虚拟的计算机,它可以在不同的操作系统上运行Java程序。JVM负责将Java程序编译后的字节码解释成机器码并执行,同时提供了垃圾回收、内存管理等功能。

JVM的编译执行

Java代码编译成字节码

Java源代码首先被编译成字节码,字节码是一种中间代码,它可以在任何平台上运行。Java编译器将Java源代码编译成字节码,然后将字节码存储在.class文件中。

字节码解释执行

JVM将字节码解释成机器指令执行。当Java程序启动时,JVM会加载字节码文件并将其解释成机器指令,然后执行这些指令。这种方式比原生代码执行速度慢,但是具有跨平台性。

JIT编译

JVM也可以使用即时编译器(JIT)将字节码编译成本地代码,以提高执行速度。JIT编译器会在程序运行时动态地将字节码编译成本地代码,然后执行本地代码。这种方式比解释执行速度快,但是需要更多的内存和CPU资源。

JVM的架构

JVM的架构可以分为以下三个部分:

  1. 类加载器(Class Loader):负责将Java类加载到JVM中,并生成对应的Class对象。Java类在JVM中的生命周期也由类加载器控制。

  1. 运行时数据区(Runtime Data Area):JVM运行时数据区分为以下几个部分:

  • 方法区(Method Area):存储类信息、常量、静态变量等。方法区是所有线程共享的。

  • 堆(Heap):存储对象实例。堆是所有线程共享的。

  • 虚拟机栈(VM Stack):存储方法的局部变量、方法参数、返回值等。每个线程都有自己的虚拟机栈。

  • 本地方法栈(Native Method Stack):和虚拟机栈类似,但是是为本地方法服务的。

  • 程序计数器(Program Counter Register):记录当前线程执行的字节码的行号。

  1. 执行引擎(Execution Engine):负责将字节码解释成机器码并执行。

JVM的类加载器

JVM使用类加载器将类加载到内存中。类加载器可以从本地文件系统、网络或其他来源加载类。JVM中有三种类加载器:

启动类加载器

启动类加载器负责加载JVM的核心类,如java.lang.Object和java.lang.ClassLoader。

扩展类加载器

扩展类加载器负责加载JVM扩展目录中的类,如JDBC驱动程序。

应用程序类加载器

应用程序类加载器负责加载应用程序的类。

JVM的类加载机制

JVM的类加载机制可以分为以下三个步骤:

  1. 加载(Loading):查找并加载字节码文件,生成对应的Class对象。

  1. 链接(Linking):将字节码文件中的符号引用解析成直接引用,并进行校验和准备工作。

  • 校验(Verification):检查字节码文件的正确性,包括语法、语义等方面。

  • 准备(Preparation):为静态变量分配内存,并设置默认值。

  • 解析(Resolution):将符号引用解析成直接引用,即将类、方法、字段等转换成内存地址。

  1. 初始化(Initialization):执行类的初始化代码,包括静态变量的赋值、静态代码块的执行等。类的初始化是线程安全的,只会被执行一次。

JVM的内存模型

JVM的内存模型分为以下两个部分:

  1. 堆(Heap):存储对象实例及其数组。堆中的对象可以被所有线程访问。

  • 新生代(Young Generation):存储新创建的对象,分为Eden区、Survivor区1和Survivor区2三部分。

  • 老年代(Old Generation):存储长时间存活的对象。

  • 永久代(Permanent Generation):存储类信息、常量等。

  1. 栈(Stack):存储方法的局部变量、方法参数、返回值等。每个线程都有自己的栈。

  • 操作数栈(Operand Stack):存储方法执行过程中的操作数。

  • 帧(Frame):存储方法的状态信息,包括局部变量表、操作数栈等。

JVM的内存管理

JVM负责内存管理,包括分配和回收对象所需的内存。JVM具有垃圾收集器,可以自动回收不再使用的对象。JVM将内存分为不同的区域,如堆、栈、方法区等。这些区域用于存储不同类型的数据,如对象、方法、局部变量等。

堆是JVM中最大的内存区域,用于存储对象。堆由许多小的内存块组成,当需要创建一个新的对象时,JVM会在堆中分配一块内存来存储对象。

栈是JVM中的另一个内存区域,用于存储方法的局部变量和操作数栈。每个线程都有自己的栈,当一个方法被调用时,JVM会在栈中为该方法创建一个新的栈帧,用于存储方法的局部变量和操作数栈。

方法区

方法区是JVM中用于存储类信息和常量池的内存区域。方法区包含了所有已加载的类信息,包括类的名称、方法、变量等。常量池是方法区的一部分,用于存储字面量和符号引用。

JVM的垃圾回收

JVM的垃圾回收机制主要是通过标记-清除算法实现的。当一个对象不再被引用时,JVM会将其标记为垃圾,等待垃圾回收器进行回收。

JVM的垃圾回收主要分为以下两个部分:

  1. 标记(Marking):遍历所有存活的对象,并将其标记为存活对象。

  1. 清除(Sweeping):清除所有未被标记的对象,并回收其占用的内存。

JVM的垃圾回收还有以下几个概念:

  • Minor GC:对新生代进行垃圾回收。

  • Major GC(Full GC):对整个堆进行垃圾回收。

  • 引用计数法(Reference Counting):记录对象被引用的次数,当引用次数为0时,回收该对象。但是该算法无法处理循环引用的情况。

  • 标记-清除算法(Mark-Sweep):标记所有存活的对象,清除所有未被标记的对象。

  • 标记-整理算法(Mark-Compact):标记所有存活的对象,将其移动到一端,清除所有未被标记的对象。

JVM的性能调优

JVM的性能调优可以从以下几个方面入手:

  1. 堆大小(Heap Size):堆的大小会影响垃圾回收的效率。如果堆太小,会导致频繁的垃圾回收,影响程序的性能;如果堆太大,会导致垃圾回收的时间变长。

  1. 垃圾回收算法(Garbage Collection Algorithm):JVM提供了多种垃圾回收算法,可以根据实际情况选择合适的算法。

  1. 垃圾回收器(Garbage Collector):JVM提供了多种垃圾回收器,每种回收器都有其特点和适用场景。

  1. 线程数(Number of Threads):JVM的垃圾回收是通过线程来执行的,可以根据机器的CPU核数和JVM的堆大小来确定线程数。

  1. 内存分配(Memory Allocation):JVM的内存分配可以通过设置-Xms和-Xmx来控制堆的大小。

JVM的安全管理

JVM具有安全管理机制,可以限制代码的访问权限,以避免恶意代码的执行。JVM中的安全管理器可以控制代码的访问权限,如访问文件系统、网络等。JVM还提供了一些安全性检查,如类型检查和访问控制。

总之,JVM是Java程序的核心,它提供了许多功能,使Java程序可以在不同的平台上运行,并具有高度的安全性和可靠性。

总结

本文介绍了JVM的架构、类加载机制、内存模型、垃圾回收和性能调优等方面的知识点。JVM是Java程序的运行环境,掌握JVM的原理对于Java程序员来说是非常重要的。


http://www.kler.cn/a/2609.html

相关文章:

  • 在 macOS 中,设置自动将文件夹排在最前
  • 基于单片机的数字气压计设计
  • MacBook Linux 树莓派raspberrypi安装Golang环境
  • 【Logstash03】企业级日志分析系统ELK之Logstash 过滤 Filter 插件
  • python中的列表推导式详解
  • Eclipse配置Tomcat服务器(最全图文详解)
  • 蓝桥杯倒计时 | 倒计时17天
  • 跳表
  • 【Node.js】身份认证,Cookie和Session的认证机制,express中使用session认证和JWT认证
  • 【TypeScript 入门】13.枚举类型
  • 方法重载和重写是什么?有什么区别
  • js的事件轮询机制
  • PHP二维数组去重(指定键名)删除重复元素
  • <Linux>进程地址空间
  • C语言-程序环境和预处理(2)
  • YOLOV8改进:如何增加注意力模块?(以CBAM模块为例)
  • 【JavaEE】线程的状态
  • 米哈游春招算法岗-2023.03.19-第一题-交换字符-简单题
  • [Python图像处理] 基于离散余弦变换的图像去噪
  • 计算机网络学习1
  • Django 实现瀑布流
  • EventLoop(回顾)
  • JVM系统优化实践(11):GC如何搞垮线上系统
  • Unity脚本类 ---- Input类,虚拟轴与插值方法
  • 第四季新星计划即将开启,博客之星取消拉票你怎么看?
  • 音乐制作:Ableton Live 11 Suite Mac