JVM(一)-内存结构

JVM(一)-内存结构

我们都知道,我们写的Java程序需要先经过编译,生成了.class文件(字节码文件)。然而,计算机并不能直接解释.class文件里面的内容,这时候就需要一个能加载、解释.class文件并且能按.class文件里的内容进行处理的一个东西–JVM。

JVM,就是Java虚拟机。它是一种规范,有针对不同系统的特定实现(Linux,Windows,macOS)。这样,相同的字节码就能在不同的系统上运行,实现了跨平台运行(Write Once, Run Anywhere)。

JVM的内存结构

JVM(一)-内存结构

上图是JDK1.8的JVM内存结构,可以看出内存结构分为程序计数器、Java虚拟机栈、本地方法栈、堆、元空间,其中程序计数器、Java虚拟机栈、本地方法栈是线程独享的(按线程隔离),其生命周期和所在线程相同,而堆、元空间是线程共享的。

程序计数器

程序计数器是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器。字节码解释器工作时通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等功能都需要依赖这个计数器来完成。

注意:程序计数器是唯一一个不会出现 OutOfMemoryError 的内存区域,它的生命周期随着线程的创建而创建,随着线程的结束而死亡。

Java虚拟机栈

每个Java方法在执行时都会创建一个栈帧(Java方法执行的内存模型)。每一个方法从被调用到执行完成的过程,就是一个栈帧在Java虚拟机栈中入栈到出栈的过程。栈是先进后出的数据结构,也就是说,后被调用的Java方法会先结束。

JVM(一)-内存结构

上图就是一个Java虚拟机栈的结构,一个Java虚拟机栈是由一个个栈帧组成的,而每个栈帧中都拥有局部变量表、操作数栈、动态链接、方法返回地址。

Java虚拟机栈可能会出现以下两种错误:
StackOverFlowError:若栈的内存大小不允许动态扩展,那么当线程请求栈的深度超过当前Java虚拟机栈的最大深度的时候,就抛出StackOverFlowError错误。
OutOfMemoryError:如果栈的内存大小可以动态扩展,如果虚拟机在动态扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常。

局部变量表
主要存放了编译期可知的各种数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference 类型,它不同于对象本身,可能是一个指向对象起始地址的引用指针,也可能是指向一个代表对象的句柄或其他与此对象相关的位置)。

操作数栈
主要作为方法调用的中转站使用,用于存放方法执行过程中产生的中间计算结果。另外,计算过程中产生的临时变量也会放在操作数栈中。

动态链接
主要服务一个方法需要调用其他方法的场景。在 Java 源文件被编译成字节码文件时,所有的变量和方法引用都作为符号引用(Symbilic Reference)保存在 Class 文件的常量池里。当一个方法要调用其他方法,需要将常量池中指向方法的符号引用转化为其在内存地址中的直接引用。动态链接的作用就是为了将符号引用转换为调用方法的内存地址的直接引用。

JVM(一)-内存结构

本地方法栈

本地方法栈与Java虚拟机栈作用相似,它们之间的区别是Java虚拟机栈为虚拟机执行Java方法服务,而本地方法栈则为虚拟机使用到的Native方法服务。本地方法被执行的时候,在本地方法栈也会创建一个栈帧,用于存放该本地方法的局部变量表、操作数栈、动态链接、方法返回地址。

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

Java堆是垃圾收集器管理的主要区域,因此也叫GC堆(Garbage Collected Heap)。从内存回收的角度(收集器一般采用分代收集算法),Java堆内存可以细分为:新生代和老年代。新生代再细分有:Eden区、Survivor0区、Survivor1区。

JVM(一)-内存结构

根据虚拟机规范,Java堆可以处于物理上的不连续内存中,只要逻辑上是连续即可。其大小可以通过-Xmx和-Xms控制。如果在堆中没有内存完成实例分配,并且堆也无法扩展时会抛出OutOfMemoryError异常。

方法区

JVM(一)-内存结构

虚拟机要使用一个类时,它需要读取并解析.class文件获取相关信息,再将信息存入到方法区。方法区用于存放类信息、字段信息、方法信息、常量、静态变量、即时编译器编译后的代码缓存等数据。

《Java 虚拟机规范》只是定义了方法区这个概念和它的作用,在不同的虚拟机实现上,方法区的实现是不同的。JDK1.8之前的方法区实现叫永久代,到了JDK1.8,方法区实现叫元空间,它取代了永久代。元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制。

JVM(一)-内存结构

元空间 (MetaSpace)替代永久代(PermGen) 的原因如下:
1、永久代受到JVM本身设置的固定大小限制,无法进行调整,而元空间使用的是直接内存,受本机可用内存的限制,虽然元空间仍旧可能溢出,但是比永久代出现的几率会更小。
2、永久代的对象是通过FullGC进行垃圾收集,也就是和老年代同时实现垃圾收集。替换成元空间以后,简化了Full GC。可以在不进行暂停的情况下并发地释放类数据,同时也提升了GC的性能。
3、在JDK1.8,合并HotSpot和JRockit的代码时, JRockit从来没有一个叫永久代的东西, 合并之后就没有必要额外的设置这么一个永久代的地方了。

Original: https://www.cnblogs.com/ayic/p/16842380.html
Author: Yi00
Title: JVM(一)-内存结构

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/684276/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • element 报错:Unexpected reserved word ‘await’

    async handleDelete() { let folderFilesIds = [1, 2] this.$confirm(‘此操作将永久删除文件, 是否继续?’, ‘提示’…

    技术杂谈 2023年5月31日
    0137
  • 设计模式-策略模式

    预先定义有着不同执行过程但 结果相同的 算法族,运行时指定所需算法。 算法族此处为一组有共同主题的有相同结果的不同算法的集合。 话不多说,看个优化案例。 优化案例 不使用策略模式的…

    技术杂谈 2023年7月11日
    082
  • python中的*和**

    简介:Python中的与*操作符使用最多的就是两种用法。 1.用做运算符,即表示乘号,*表示次方。 用于指定函数传入参数的类型的。*用于参数前面,表示传入的多个参数将按照元组的形式…

    技术杂谈 2023年7月25日
    0109
  • PYTORCH: 60分钟

    什么是PyTorch? PyTorch 是一个基于Python的科学计算包,有两大用途: NumPy的替代品,可使用GPUs和其它加速器的强大功能 一个用于实现神经网络的自动微分库…

    技术杂谈 2023年7月25日
    096
  • 自动化测试之争:code vs codeless

    在TesterHome看到的一个话题,当我们选择做自动化时是否需要code 或者codeless。 code方案 用code去做自动化,实现过程就是拿个IDE撸代码。 python…

    技术杂谈 2023年5月31日
    0107
  • opencv-python函数

    opencv-python读取、展示和存储图像 cv2.imshow(windows_name, image) 函数参数一: 窗口名称(字符串)函数参数二: 图像对象,类型是num…

    技术杂谈 2023年6月21日
    0109
  • 如何正确的中断线程?你的姿势是否正确

    Java停止线程的逻辑(协同、通知) 在Java程序中,我们想要停止一个线程可以通过interrupt方法进行停止。但是当我们调用interrupt方法之后,它可能并不会立刻就会停…

    技术杂谈 2023年7月11日
    097
  • 一些常用的 std 类型

    【 std::allocator】 标准库中包含一个名为allocator的类,允许我们将分配和初始化分离。使用allocator通常会提供更好的性能和更灵活的内存管理能力。 标准…

    技术杂谈 2023年5月31日
    0129
  • Javaweb学习-HTML

    ; ; 重新开始HTML,之前学的都忘了 posted @2022-03-24 21:27 HelloHui 阅读(7 ) 评论() 编辑 Original: https://ww…

    技术杂谈 2023年6月21日
    0107
  • Phaser.js All In One

    Phaser.js All In One HTML5 Canvas 2D Game Engine Phaser.js https://phaser.io/ https://phas…

    技术杂谈 2023年6月1日
    090
  • 字节跳动-财经-校招内推

    【团队介绍】 我们为字节跳动生态的抖音电商、直播、教育、健康、内容付费等场景服务,依托字节跳动的科技能力和产品,为用户提供更好的支付、消费金融、保险等金融服务体验。科技创新,普惠大…

    技术杂谈 2023年5月31日
    0115
  • 深入浅出SpringSecurity

    SpringSecurity学习 SpringSecurity简介 安全框架的概述 什么是安全框架?是为了解决安全问题的框架。如果没有安全框架,我们需要手动处理每个资源的访问控制,…

    技术杂谈 2023年7月11日
    0106
  • 阅读别人的代码,是一种怎样的体验

    原创:微信公众号 【阿Q说代码】,欢迎分享,转载请保留出处。 之前写过一篇名为《看了同事写的代码,我竟然开始默默的模仿了。。。》的文章,今天偶然间看了下后台数据,大吃一惊。该文章的…

    技术杂谈 2023年7月11日
    092
  • 动态创建的 CEdit 被限制长度,增加 ES_AUTOHSCROLL 属性;被无法Tab激活焦点,增加 WS_TABSTOP 属性(转)

    动态创建的 CEdit 被限制长度,增加 ES_AUTOHSCROLL 属性;被无法Tab激活焦点,增加 WS_TABSTOP 属性。 CEdit m_editUrl; // ES…

    技术杂谈 2023年5月31日
    0113
  • 非自交任意多边形与矩形框的交集面积计算方法

    非自交任意多边形与矩形框的交集面积计算方法 1、应用背景 在对象识别的AI计算时,有时需要限定检测区域,即目标对象落在限定区域内有效,在区域外忽略。转换为数学模型为:目标检测框与限…

    技术杂谈 2023年6月21日
    096
  • 阿里云高防回源IP的限制

    高防回源IP 只能回到非阿里云的IP 高防所在阿里云账号下的SLB或者ECS IP *以及非阿里云账号下的SLB IP 一共三种情况。 posted on2022-05-17 15…

    技术杂谈 2023年5月31日
    0116
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球