JVM五大内存模型

这篇具有很好参考价值的文章主要介绍了JVM五大内存模型。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

什么是JVM

JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一个虚构出来的计算机,有着自己完善的硬件架构,如处理器、堆栈等。

JVM的作用

Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码( 字节码 ),就可以在多种平台上不加修改地运行。

Java文件必须先通过一个叫javac的编译器,将代码编译成class文件,然后通过JVM把class文件解释成各个平台可以识别的机器码,最终实现跨平台运行代码。

JVM内存模型

JVM内存模型可以分为两个部分,堆和方法区是所有线程共有的,而虚拟机栈,本地方法栈和程序计数器则是线程私有的。

堆(Heap)

Java堆(Heap),是Java虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。

可能存在的异常

  1. OutOfMemoryError:当堆中没有足够的内存分配给新的对象时抛出。这可能是由于堆空间不足、内存泄漏或对象过多等原因导致。

  2. StackOverflowError:当线程的调用栈空间超过其限制时抛出。这通常是由于无限递归或者方法调用层次过深引起的。

  3. HeapDumpOutOfMemoryError:当堆内存不够用时,JVM可能会生成一个堆转储文件(Heap Dump)以供分析。这通常发生在OutofMemoryError之后,用于帮助开发人员诊断内存问题。

  4. PermGen space/ Metaspace OutOfMemoryError:在Java 7及之前的版本中,常见于永久代(PermGen)内存区域不足的情况。而在Java 8及之后的版本中,永久代被元空间(Metaspace)所取代,因此抛出的错误会是Metaspace OutOfMemoryError。

  5. ConcurrentModeFailureException:在并发标记清除垃圾回收器(CMS)中,当GC线程无法跟上应用程序生成的垃圾量时,会抛出此异常。这可能是由于堆中对象数量过多或者垃圾回收器参数配置不合理导致。

方法区(Method Area)

方法区(Method Area)与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

可能存在的异常

  1. OfMemoryError:当方法区没有足够的内存分配给新的类元数据、常量池等时抛出。这可能是由于方法区空间不足、加载过多的类或者大量的字符串常量等原因导致。
  2. PermGen space/ Metaspace OutOfMemoryError:在Java 7及之前的版本中,常见于永久代(PermGen)内存区域不足的情况。而在Java 8及之后的版本中,永久代被元空间(Metaspace)所取代,因此抛出的错误会是Metaspace OutOfMemoryError。
  3. ClassLoader相关异常:在方法区中,类加载器负责加载和链接类的过程。如果类加载器出现问题,可能会导致ClassNotFoundException、NoClassDefFoundError等异常。
  4. 频繁Full GC:如果方法区中存储的类元数据、常量池等对象无法被垃圾回收,则可能导致频繁进行Full GC(全局垃圾回收),从而影响应用程序的性能。

需要注意的是,在Java 8及之后的版本中使用元空间(Metaspace)替代了永久代(PermGen),因此一些特定于永久代的异常,如PermGen space OutOfMemoryError,在Java 8及之后的版本中不再出现。而Metaspace OutOfMemoryError则是对应的异常。

程序计数器(Program Counter Register)

程序计数器是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器。

在JVM的概念模型里,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。

分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。

JVM的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,为了各条线程之间的切换后计数器能恢复到正确的执行位置,所以每条线程都会有一个独立的程序计数器。

当线程正在执行一个Java方法,程序计数器记录的是正在执行的JVM字节码指令的地址;如果正在执行的是一个Natvie(本地方法),那么这个计数器的值则为空(Underfined)。

可能存在的异常

程序计数器可能存在的异常情况主要是线程相关的问题,例如:

  1. 线程死循环:如果线程陷入死循环,程序计数器会一直指向循环的字节码指令地址,不会发生变化。这可能导致程序无法继续执行其他逻辑。

  2. 线程切换错误:在多线程环境中,JVM会通过线程切换来实现并发执行。程序计数器记录了每个线程当前执行的位置,在线程切换时需要正确保存和恢复计数器的值。如果出现错误,可能导致线程执行位置错乱或者执行结果异常。

  3. 虚拟机实现错误:JVM的实现可能存在bug或者错误,导致程序计数器的行为异常。这种情况比较少见,但仍有可能发生。

虚拟机栈(JVM Stacks)

与程序计数器一样,Java虚拟机栈(Java Virtual Machine Stacks)也是线程私有的,它的生命周期与线程相同。

虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

可能存在的异常

  1. StackOverflowError:当线程的调用栈空间超过其限制时抛出。这通常是由于无限递归或者方法调用层次过深引起的。每个线程在JVM中都有一个对应的虚拟机栈,当栈空间耗尽时会抛出StackOverflowError。

  2. OutOfMemoryError:当虚拟机栈无法继续分配新的栈帧时抛出。每个线程在JVM中都有一个对应的虚拟机栈,用于保存方法调用的信息。如果创建的线程过多或者每个线程的栈帧太大,将消耗掉可用的虚拟机栈空间,导致无法分配新的栈帧,从而抛出OutOfMemoryError。

  3. StackOverflowError和OutOfMemoryError都是虚拟机栈相关的异常,但它们的原因和解决方法不同。StackOverflowError通常是由于方法调用层次过深或者无限递归引起的,需要检查代码逻辑并修复。而OutOfMemoryError则可能是由于线程数过多或者每个线程的栈帧太大,可以通过调整JVM参数来增加虚拟机栈的大小。

本地方法栈(Native Method Stacks)

本地方法栈(Native Method Stacks)与虚拟机栈所发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的Native方法服务。

可能存在的异常

  1. StackOverflowError:当本地方法栈空间超过其限制时抛出。本地方法栈的大小是由JVM参数决定的,一般较小。如果本地方法递归调用层次太深或者本地方法栈帧太大,超出了栈空间限制,就会抛出StackOverflowError。

  2. OutOfMemoryError:当无法分配新的本地方法栈帧时抛出。本地方法栈的大小是有限的,如果创建的线程过多或者每个线程的本地方法栈帧太大,将耗尽可用的本地方法栈空间,导致无法分配新的栈帧,从而抛出OutOfMemoryError。文章来源地址https://www.toymoban.com/news/detail-614045.html

到了这里,关于JVM五大内存模型的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JVM原理:JVM运行时内存模型(通俗易懂)

    做了几年开发,平时除了写代码造BUG和修复BUG之外,偶尔也会遇到反馈说程序较慢问题,要对程序性能排查与优化就得更深入学习,学习JVM可以帮助我们加深对JAVA的理解,让我们具备一定的性能排查与调优的能力,无非就是让程序别太卡或者别挂了,那挂了目前我遇到的主要

    2024年02月08日
    浏览(38)
  • 四、JVM-对象内存模型

    一个Java对象在内存中包括3个部分:对象头、实例数据和对齐填充 数据 内存 – CPU 寄存器 -127 补码 10000001 - 11111111 32位的处理器 一次能够去处理32个二进制位 4字节的数据 64位操作系统 8字节 2的64次方的寻址空间 指针压缩技术 JDK1.6出现的 开启了指针压缩 什么时候指针压缩会

    2024年02月14日
    浏览(22)
  • JVM内存模型深度解读

            JVM(Java Virtual Machine,Java虚拟机)对于Java开发者和运行 Java 应用程序而言至关重要。其重要性主要体现在跨平台性、内存管理和垃圾回收、性能优化、安全性和稳定性、故障排查与性能调优等方面。今天就下学习一下 JVM 的内存模型。         JVM 内存模型(

    2024年03月19日
    浏览(35)
  • JVM oop内存模型

    1、非数组对象 InstaceOopDesc 2、数组对象  arrayOopDesc         2.1 基本数据类型数组 typeArrayOopDesc         2.2 引用类型数组 objArrayOopDesc  3、MarkOopDesc         存放锁信息、分代年龄等 1、InstanceKlass是JVM中表示类的对象的数据结构。JVM在加载class时,会创建 instanceKlass ,表示其元

    2024年02月12日
    浏览(30)
  • JVM——内存模型

      这里与局部变量自增不同,局部变量调用iinc是在局部变量表槽位上进行自增。  静态变量是在操作数栈自增。 这里的主内存和工作内存时再JMM里的说法。  因为操作系统是时间片切换的多个线程轮流使用CPU. JMM中通过synchronized(同步)保证原子性。 使用synchronized减i+

    2024年02月11日
    浏览(19)
  • JVM之内存模型

    首先说明下 JVM内存模型 和 Java内存模型 这是两个不同的概念,不要搞混淆了。 JVM内存模型定义了Java程序在运行时如何分配、使用和释放内存,跟存储和执行相关,也就是常说的运行时数据区域。 Java内存模型(Java Memory Model,简称 JMM)是一种规范,定义了线程和主内存之间

    2024年02月08日
    浏览(21)
  • JVM学习05:内存模型

    很多人将 java 内存结构 与 java 内存模型 傻傻分不清,java 内存模型是 **Java Memory Model(JMM)**的意思。 JMM 定义了一套在多线程读写共享数据时(成员变量、数组)时,对数据的可见性、有序性、和原子性的规则和保障。 原子性是指一个操作是 不可中断 的。即使在多个线程一

    2024年02月04日
    浏览(29)
  • 认识JVM的内存模型

    从上一节了解到整个JVM大的内存区域,分为线程共享的heap(堆),MethodArea(方法区),和线程独享的 The pc Register(程序计数器)、Java Virtual Machine Stacks(Java虚拟机栈)、Native Method Stacks(本地方法栈),如下图 同时也大概了解到各个内存区域主要存储的数据类型,根据之前

    2024年02月10日
    浏览(26)
  • JVM内存模型详解

    JVM内存模型和Java内存模型都是面试的热点问题,名字看感觉都差不多,实际上他们之间差别还是挺大的。     通俗点说,JVM内存结构是与JVM的内部存储结构相关,而Java内存模型是与多线程编程相关@mikechen。   什么是JVM JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一个虚

    2023年04月13日
    浏览(50)
  • 进阶课程1:jvm内存模型

    在Java中,局部变量和成员变量的区别如下: 定义的位置不同:成员变量定义在类中,而局部变量定义在方法中或者方法的声明上。 在内存中的位置不同:成员变量存储在堆内存的对象中,而局部变量存储在栈内存的方法中用。 生命周期不同:成员变量随着对象的创建而存在

    2024年02月11日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包