在Java里什么是JVM_Java虚拟机运行原理解析

发布时间 - 2026-01-24 00:00:00    点击率:
JVM是用C/C++编写的本地进程,非虚拟机;启动时加载字节码、划分真实内存区域,通过系统调用申请资源;执行分三步:ClassLoader加载、解释器初执行、JIT编译热点代码为机器码。

JVM 是 Java 程序真正“跑起来”的那个进程,不是抽象概念,也不是后台服务——你执行 java HelloWorld 的瞬间,操作系统就启动了一个 JVM 进程,它加载字节码、分配内存、调用系统资源,最后把你的逻辑变成 CPU 能执行的指令。


什么是 JVM?它不是“虚拟电脑”,而是一个 C/C++ 写的本地程序

很多人误以为 JVM 是像 VirtualBox 那样的完整硬件模拟器,其实不是。JVM 是一个用 C/C++ 编写的可执行程序(Windows 上是 java.exe,Linux/macOS 是 java 可执行文件,背后依赖 libjvm.solibjvm.dylib)。它被 JDK 安装到磁盘,运行时才加载进内存,成为一个独立进程。

  • JVM 启动后,会在内存中划分出堆、栈、元空间等区域——这些不是“虚拟地址”,而是真实由操作系统分配的内存段
  • 它不直接操作硬件,而是通过 OS 的系统调用(如 mmappthread_create)申请资源
  • 不同平台的 JVM 二进制不同(比如 Windows 的 java.exe 和 Linux 的 java 不能互换),但它们都遵守同一套字节码规范,这才实现“一次编译,到处运行”

Java 代码怎么变成 CPU 指令?关键在三步:加载 → 解释/编译 → 执行

HelloWorld.java 到屏幕输出,中间没有魔法,只有明确的流水线:

  • javac HelloWorld.java → 生成 HelloWorld.class(标准字节码,平台无关)
  • JVM 的 ClassLoader 把 class 文件读入内存,放进 方法区(Metaspace)
  • Execution Engine 开始干活:
    • 先用 解释器 逐行翻译字节码为机器指令(启动快,但慢)
    • 对反复执行的代码(如循环体、热点方法),JIT 编译器(如 HotSpot 的 C1/C2) 会将其编译成本地机器码,缓存复用

也就是说,同一个 for (int i = 0; i ,第一次运行可能被解释执行,第 10 次可能已变成 CPU 直接跑的汇编指令。

为什么改了 JVM 参数程序就行为不同?因为你在动它的“身体结构”

JVM 启动参数不是配置开关,而是直接干预内存布局和执行策略。几个最常踩坑的点:

  • -Xms512m -Xmx2g:强制堆初始和最大为 512MB / 2GB —— 如果只设 -Xmx 不设 -Xms,堆会动态扩容,触发多次 GC;设成一样可避免扩容抖动
  • -XX:MetaspaceSize=256m:元空间(存类定义)初始阈值,超了会触发 Full GC;JDK 8+ 没有 PermGen,别再配 -XX:PermSize
  • -XX:+UseG1GC:显式启用 G1 垃圾回收器 —— 不同 GC 算法对停顿时间、吞吐量影响巨大,Web 服务通常选 G1,低延迟场景考虑 ZGC(需 JDK 11+)
  • -XX:+PrintGCDetails -Xlog:gc*(JDK 9+):不加日志,等于“盲开飞机”;GC 行为必须可观测

常见错误背后,几乎都是 JVM 内存模型理解偏差

很多 OutOfMemoryError 并不是“内存不够”,而是用错了区域:

  • java.lang.OutOfMemoryError: Java heap space → 对象太多,堆撑爆了(检查是否有集合类长期持有引用、缓存未清理)
  • java.lang.OutOfMemoryError: Metaspace → 加载了太多动态类(如 Spring Boot + 热部署、大量反射生成代理类)
  • java.lang.StackOverflowError → 单个线程栈帧太多(常见于无限递归、过深的 AOP 嵌套);可通过 -Xss256k 调整单线程栈大小(默认一般 1MB)
  • 没报错但卡顿?可能是

    GC 频繁或 JIT 编译阻塞 —— 此时 jstat -gc jstack 比看日志更管用

JVM 不是黑盒,它每个行为都有对应的数据结构和系统调用路径。真正卡住问题的,往往不是语法或框架,而是忘了它本质是个进程——有 PID、占内存、发系统调用、受 OS 调度。调试时先问自己:这个现象,发生在哪个内存区?哪个线程?有没有触发 GC 或 JIT?答案通常就在那里。


# linux  # java  # js  # windows  # 操作系统  # 电脑  # 字节  # 虚拟机  # ssl  # mac  #   # ai  # c++  # macos 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 百度输入法ai组件怎么删除 百度输入法ai组件移除工具  EditPlus中的正则表达式实战(6)  宙斯浏览器文件分类查看教程 快速筛选视频文档与图片方法  如何快速搭建支持数据库操作的智能建站平台?  JavaScript 输出显示内容(document.write、alert、innerHTML、console.log)  大连网站制作公司哪家好一点,大连买房网站哪个好?  三星网站视频制作教程下载,三星w23网页如何全屏?  Javascript中的事件循环是如何工作的_如何利用Javascript事件循环优化异步代码?  Laravel怎么发送邮件_Laravel Mail类SMTP配置教程  iOS UIView常见属性方法小结  Laravel Vite是做什么的_Laravel前端资源打包工具Vite配置与使用  如何用已有域名快速搭建网站?  iOS中将个别页面强制横屏其他页面竖屏  Win11怎么开启自动HDR画质_Windows11显示设置HDR选项  SQL查询语句优化的实用方法总结  免费网站制作appp,免费制作app哪个平台好?  Laravel事件和监听器如何实现_Laravel Events & Listeners解耦应用的实战教程  齐河建站公司:营销型网站建设与SEO优化双核驱动策略  作用域操作符会触发自动加载吗_php类自动加载机制与::调用【教程】  如何用西部建站助手快速创建专业网站?  Laravel怎么实现一对多关联查询_Laravel Eloquent模型关系定义与预加载【实战】  Laravel如何使用Collections进行数据处理?(实用方法示例)  电视网站制作tvbox接口,云海电视怎样自定义添加电视源?  Android仿QQ列表左滑删除操作  Laravel怎么多语言本地化设置_Laravel语言包翻译与Locale动态切换【手册】  如何在IIS中新建站点并配置端口与IP地址?  使用豆包 AI 辅助进行简单网页 HTML 结构设计  Laravel如何使用Service Provider注册服务_Laravel服务提供者配置与加载  如何快速完成中国万网建站详细流程?  合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?  HTML 中动态设置元素 name 属性的正确语法详解  如何挑选高效建站主机与优质域名?  移动端手机网站制作软件,掌上时代,移动端网站的谷歌SEO该如何做?  矢量图网站制作软件,用千图网的一张矢量图做公司app首页,该网站并未说明版权等问题,这样做算不算侵权?应该如何解决?  东莞市网站制作公司有哪些,东莞找工作用什么网站好?  如何用y主机助手快速搭建网站?  如何在IIS7上新建站点并设置安全权限?  Laravel如何集成第三方登录_Laravel Socialite实现微信QQ微博登录  Laravel 419 page expired怎么解决_Laravel CSRF令牌过期处理  历史网站制作软件,华为如何找回被删除的网站?  Windows驱动无法加载错误解决方法_驱动签名验证失败处理步骤  Internet Explorer官网直接进入 IE浏览器在线体验版网址  利用vue写todolist单页应用  太平洋网站制作公司,网络用语太平洋是什么意思?  微信小程序制作网站有哪些,微信小程序需要做网站吗?  php静态变量怎么调试_php静态变量作用域调试技巧【解答】  Laravel如何使用Sanctum进行API认证?(SPA实战)  深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?  网站制作壁纸教程视频,电脑壁纸网站?  Laravel怎么实现模型属性转换Casting_Laravel自动将JSON字段转为数组【技巧】