欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 产业 > JVM理解(通俗易懂)

JVM理解(通俗易懂)

2025/4/24 15:42:03 来源:https://blog.csdn.net/weixin_42531931/article/details/147296423  浏览:    关键词:JVM理解(通俗易懂)

虽然网上有很多关于JVM的教程,但是都天花乱坠,很多都是一上来就JVM内存模型、JVM双亲委派等等,(可能我比较菜看不懂)。于是我自己决定写一篇能看懂的文章~如果有看不懂我就自己百度,大家有什么疑问也可以评论区交流~ 欢迎指点我的Error~

JVM概念

JVM大家都知道,就Java虚拟机嘛。但JVM名称的由来实际上是Java Virtual Machine 的缩写~
它是一台虚拟出来的计算机,能够运行在咱们平时所用的Window/Linux/Mac电脑上,也正因如此,Java能够实现跨平台性。
其次,Java虚拟机不与硬件直接交互,而是直接作用于操作系统。通过上面描述的操作系统能够帮我们完成与硬件的交互工作。大家可以看这张图:
在这里插入图片描述

JVM体系

我们平时所写的Java文件,我们都知道,它是会被编译器编译成二进制的.class后缀的文件。后续的执行流程,涉及几个非常重要的概念,我分小标题讲解一下。
溯石

类加载器(Class Loader)

JVM执行Java文件时,会通过类加载器加载对应的class文件到JVM中,此时正式进入JVM执行环节。

方法区(Method Area)

方法区主要存放元数据信息,如类信息、常量、静态变量、编译后到代码等。类加载器将class文件会先放入方法区。

堆区(Heap)

在Java内存架构中,堆内存(Heap)是对象实例的专属存储区域。垃圾收集器(Garbage Collector, GC)的核心使命便是扫描堆内存,识别并回收那些不再被引用的"垃圾对象",从而释放内存空间供新对象分配使用。

在JDK 1.8的里程碑式更新中,永久代(Permanent Generation, PermGen)这一传统方法区实现被彻底移除,取而代之的是元空间(Metaspace)。发展历程如下所示:

版本永久代变化
JDK6永久代用于存储类的元数据,包括类的名称、字段、方法、常量池等信息。永久代有固定大小限制,由-XX:MaxPermSize参数设置,当类加载过多时,容易出现java.lang.OutOfMemoryError: PermGen space错误。
JDK7永久代开始被元空间替代,元空间使用本地内存,允许更灵活的内存管理。虽然永久代仍然存在,但部分元数据已开始迁移到元空间。
JDK8永久代被完全移除,元空间成为存储类元数据的区域。元空间使用本地内存,不再受限于JVM堆内存,默认情况下会根据应用需要动态调整大小。元空间的大小可以通过-XX:MetaspaceSize和-XX:MaxMetaspaceSize等参数控制。

栈区(Stack)

栈区是我们代码的运行空间,栈区有虚拟机栈与本地方法栈。咱们编写的每一个方法都会在栈区执行,同时还保存了方法的局部变量、操作数栈和返回地址等信息。栈区属于线程独享区域~

本地方法栈(Native Method Stack)

我们查看Thread源码时,会惊奇的发现,源码几乎看不到什么实现,只有一个start0()方法,用native修饰且无方法体。它是由C来实现的,一般此类方法会被放入本地方法栈。
在这里插入图片描述

虚拟机栈
  • 异常说明
    当Java线程执行过程中,若其方法调用的栈帧深度超出了虚拟机栈预设的最大容量限制,系统将抛出StackOverflowError。这种错误常见于深度递归场景——每次递归调用都会在栈中新增一个栈帧,若递归终止条件缺失或栈容量不足,栈帧将持续累积直至突破栈深度阈值。
    现代JVM(如HotSpot)支持虚拟机栈的动态扩展机制。当线程执行需要更多栈空间时,JVM会尝试扩展栈的存储空间。然而,这种扩展并非无限制:若系统内存资源已耗尽,或扩展后的栈空间仍无法满足需求,JVM将抛出OutOfMemoryError。这种错误表明程序对内存的需求已超出当前系统可分配资源的极限,需通过优化内存使用或增加堆外存配置来解决。

  • 生命周期
    在Java内存体系中,栈(Stack)作为线程私有的内存区域,其内存管理机制具有独特特性。与堆(Heap)不同,栈不存在垃圾回收机制,因为栈帧的分配与回收遵循严格的LIFO(后进先出)原则。当方法执行完毕时,其对应的栈帧会自动弹出栈并释放内存,无需依赖垃圾回收器的介入。
    栈的生命周期与所属线程紧密绑定。当线程被创建时,JVM会为其分配独立的栈空间;当线程终止时,其栈内存也随之销毁,实现了资源的自动回收。这种设计保证了线程间栈内存的隔离性,避免了多线程环境下的内存冲突。

    在栈内存的分配层面,以下三类数据会在栈中占据空间:
    基本类型变量:包括byte、short、int、long、float、double、char、boolean这8种基本数据类型的局部变量。
    对象引用变量:存储对象在堆内存中的地址指针,而非对象本身。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词