Java - JVM内存区域的划分

Java8-JVM内存区域划分白话解读 java作为一款能够自动管理内存的语言,与传统的c/c++语言相比有着自己独特的优势。虽然我们无需去管理内存,但为了防范可能发生的异常,我们需要对java内部数据如何存储有一定了解,已应对突发问题,写出更好的程序java程序在被编译成字节码后,由JVM执行,执行期间产生的所有数据,会被分门别类的存储在JVM预设好的区域里,具体情况如下所示以下为java8的内存分布图​Tips:红色是线程共享的,黄色是线程私有的接下来我们着重讨论Java8中的内存分布情况这部分内存在JVM中,由JVM直接分配,初始大小、最大 阅读详情

Java 程序运行时,需要在内存中分配空间。为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。

分配:通过关键字new创建对象分配内存空间,对象存在堆中。
释放 :对象的释放是由垃圾回收机制决定和执行的

JVM的内存可分为3个区:

堆(heap)
栈(stack)
方法区(method,也叫静态区)

 

堆区: 程序员自己申请,运行时线程公有

通过new生成的对象都存放在堆中,对于堆中的对象生命周期的管理由Java虚拟机的垃圾回收机制GC进行回收和统一管理


jvm只有一个堆区(heap),且被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身和数组本身;
优点是可以动态分配内存大小,缺点是由于动态分配内存导致存取速度慢。

虚拟机栈: 系统自己分配,运行时线程私有

栈内存主要是存放一些基本类型的变量和对象的引用变量。最典型的就是我们new一个对象时,对象名作为变量就存放在栈内存中


栈内存有一个很重要的特殊性——在栈中的数据可以共享(已存在的值不会再次创建)
int a = 3;
int b = 3;
(编译器先处理int a =3;首先它会在栈中创建一个变量为a的引用,然后查找栈中是否有3这个值,如果没找到,就将3存放进来,然后将a指向3。接着处理int b)


每个方法执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等。局部变量表存放了编译器可知的各种基本数据类型、对象引用和returnAddress类型


每个方法从调用直至完成的过程,都对应着一个栈帧从入栈到出栈的过程。每当一个方法执行完成时,该栈帧就会弹出栈帧的元素作为这个方法的返回值,并且清除这个栈帧,Java栈的栈顶的栈帧就是当前正在执行的活动栈,也就是当前正在执行的方法,方法的调用过程也是由栈帧切换来产生结果。


在JVM规范中,对这个区域规定了两种异常情况:
1.如果线程请求的栈深度大于虚拟机允许的深度,将抛出StackOverflowError异常;
2.如果虚拟机栈可以动态扩展,在扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常。

本地方法栈:


和虚拟机栈所发挥的作用基本一致,不同的是:

虚拟机栈为虚拟机执行Java方法(字节码)服务
本地方法栈则为虚拟机使用到的Native方法服务
本地方法栈也会抛出StackOverflowError和OutOfMemoryError异常。

方法区(静态区):

是各个线程共享的内存区域,它用于存储class二进制文件,包含所有的class和static变量,包含了虚拟机加载的类信息、常量(常量池)、静态变量(静态域)、即时编译后的代码等数据。


方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。


被所有的线程共享,方法区包含所有的class(class是指类的原始代码,要创建一个类的对象,首先要把该类的代码加载到方法区中,并且初始化)和static变量。

常量池:在编译期间就将一部分数据存放于该区域,包含以final修饰的基本数据类型的常量值、String字符串。(在java6时它是方法区的一部分;1.7又把他放到了堆内存中;1.8之后出现了元空间,它又回到了方法区。)


静态域:存放类中以static声明的静态成员变量。

程序计数器:当前线程所执行的行号指示器。通过改变计数器的值来确定下一条指令,比如循环,分支,跳转,异常处理,线程恢复等都是依赖计数器来完成。
程序计数器:
一个非常小的内存空间,用来保存程序执行到的位置(线程私有),它可以看作是当前线程所执行的字节码的行号指示器。

Metaspace元空间:

在JDK1.8中,永久代已经不存在,存储的类信息、编译后的代码数据等已经移动到了MetaSpace(元空间)中,元空间并没有处于堆内存上,而是直接占用的本地内存(NativeMemory)。
元空间的本质和永久代类似,都是对JVM规范中方法区的实现。
元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。
元空间的大小仅受本地内存限制,可以指定元空间大小。


Java8为什么要将永久代替换成Metaspace?
1、字符串存在永久代中,容易出现性能问题和内存溢出。
2、类及方法的信息等比较难确定其大小,因此对于永久代的大小指定比较困难,太小容易出现永久代溢出,太大则容易导致老年代溢出。
3、永久代会为 GC 带来不必要的复杂度,并且回收效率偏低。
4、Oracle 可能会将HotSpot 与 JRockit 合二为一。

 基本数据类型

int a = 3;
int b = 3;

编译器先处理 int a = 3;首先它会在栈中创建一个变量为 a 的引用,然后查找有没有字面值为3的地址,没找到,就开辟一个存放3这个字面值的地址,然后将 a 指向3的地址。

接着处理 int b = 3;在创建完 b 这个引用变量后,由于在栈中已经有3这个字面值,便将 b 直接指向3的地址。这样,就出现了 a 与 b 同时均指向3的情况。

对象

public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

一个类通过使用new运算符可以创建多个不同的对象实例,这些对象实例将在堆中被分配不同的内存空间,改变其中一个对象的状态不会影响其他对象的状态:

        Person one = new Person("小明",15);
        Person two = new Person("小王",17);

在堆内存中只创建了一个对象实例,在栈内存中创建了两个对象引用,两个对象引用同时指向一个对象实例。

        Person one = new Person("小明",15);
        Person two = one;

数组
数组是一种引用类型,数组用来存储同一种数据类型的数据。

一旦初始化完成,即所占的空间就已固定下来,即使某个元素被清空,但其所在空间仍然保留,因此数组长度将不能被改变。

int[] array = new int[5]

首先会在栈中创建引用变量,在堆中开辟5个int型数据的空间,该引用变量存放数组首地址,即实现数组名来引用数组。

 

全网最全-QCC51xx-QCC30xx(TWS)系列从入门到精通开发教程汇总(持续更新中) QCC3040开发笔记之基本介绍(0) QCC3040开发笔记之开发环境搭建(1) QCC3040开发笔记之debug调试(trb调试,usbt调试,adb调试,WIFI调试)(2) QCC3040开发笔记之按键配置(3) QCC3040开发笔记之按键切换(4) QCC3040开发笔记之按键逻辑(5) QCC3040开发笔记之tone(6) QCC3040开发笔记之提示音(7) QCC3040开发笔记之bitserial接口(8) QCC3040开发笔记之双mic+AEC+ANC(9... 阅读详情

相关推荐

FCN---训练cityspaces

未经允许,不要随意转载! 最近想试试用FCN训练自己的数据集,想想标注是一件很费劲的事,于是就想到了用其他库里的数据,这里选用了cityspaces,默认已经配置好FCN. 1、下载cityspaces https://www.cityscapes-dataset.com/ 需要注册一个账号 cityspaces包含2...

wangyu088的专栏 2030

Java 内存管理详解:一文搞懂 JVM 的“分区套路”

Java内存管理是程序性能优化的关键。文章系统讲解了JVM内存结构:线程私有的程序计数器、虚拟机栈(含栈溢出问题)和本地方法栈;共享的堆内存(分新生代/老年代)和方法区(JDK8后改为元空间)。特别分析了字符串常量池、直接内存等特殊区域的作用,并针对各类内存溢出问题(堆OOM、栈溢出、元空间OOM等)给出解决方案。理解内存分区机制有助于快速定位性能问题,合理设置JVM参数,是Java开发者必备的底层知识。

m0_74023628的博客 1109

PX4从放弃到精通(十一):混控及PWM输出

文章目录前言一、混控脚本二、使用步骤1.引入库2.读入数据总结 前言 一个人可以走的更快,一群人才能走的更远,交流学习加qq:2096723956 更多保姆级PX4+ROS学习视频:https://b23.tv/ZeUDKqy 分享知识,传递正能量,如有疏漏或不当之处,恳请指出. 一、混控脚本 混控脚本定义了不同 示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。 二、使用步骤 1.引入库 代码如下(示例): import numpy as np import pand

超维空间科技的博客 1万+

jvm-内存管理

JVM的内存区域划分 根据《Java虚拟机规范》的规定,运行时数据区通常包括这几个部分: 程序计数器(Program Counter Register)、Java栈(VM Stack)、本地方法栈(Native Method Stack)、方法区(Method Area)、堆(Heap)。 3.1 内存分配 3.1.1 程序计数器 想必学过汇编语言的朋友对程序计数器这个概念并不陌生,在汇编语言中,程序计数器是指CPU中的寄存器,它保存的是程序当前执行的指令的地址(也可以说保存下一...

sinat_34814635的博客 1447

手把手教你学simulink(90.1)--直流电动机实例:基于Simulink的基本模型的直流电动机(DC Motor)建模

直流电动机(DC Motor)因其结构简单、控制方便和良好的调速性能,广泛应用于各种工业自动化、机器人技术、家用电器以及航空航天等领域。为了更好地理解和应用直流电动机的工作原理及其控制系统,本项目旨在通过Simulink对直流电动机进行基本模型的建模与仿真。

MHD0815的博客 439

“华为杯”研究生数学建模竞赛2019年-【华为杯】D题:汽车行驶工况构建(附获奖论文和MATLAB代码实现)

映了汽车道路行驶的运动学特征。准差、加速度标准差这九个特征参数用于后续的数据分析,建立了合理的汽车运动特征评。特征参数与所属类特征参数的特征值的相关性大小替代误差进行排序的,计算得到汽车行。对于问题一,我们首先对原始数据进行了时间变量转换,将原本的年月日时分秒的计。紧接着进行了运动学片段的划分,引入九个特征参数,通过主成分分析、本文研究的是汽车行驶工况构建,汽车行驶工况是描述汽车行驶的速度。的合理性评价标准,对两种方法都进行了合理性评价,得到的。进行了合理性评价,得到了最优的汽车行驶工况曲线。

getusushu的博客 1000

jvm运行时的内存结构

方法区:存储类信息、常量、静态变量、即时编译后的代码。堆:存放所有对象实例和数组,是垃圾回收的主要区域。栈:每个线程都有自己的栈,存储局部变量和方法调用信息。程序计数器:保存当前线程执行的字节码指令地址。本地方法栈:支持本地方法的调用。运行时常量池:方法区的一部分,存储类的常量池信息。直接内存:由Java通过ByteBuffer类直接操作的内存区域。了解这些内存区域及其工作原理对于优化Java应用程序的性能、排查内存问题以及进行垃圾回收调优具有重要意义。​。

Flying_Fish_roe的博客 983

【ubuntu24.04】auto remove后,重启,kernel panic ,please reboot your computer vfs unable to mount root fs

Ubuntu 24.04系统在运行auto remove后出现内核恐慌(kernel panic)无法启动,显示"VFS: unable to mount root fs"错误。该问题是由于当前内核被清除导致系统无法挂载根分区。解决步骤包括:1)尝试用GRUB菜单中的旧内核启动;2)在GRUB中临时编辑启动参数;3)使用Ubuntu启动盘进行chroot修复;4)使用Boot-Repair工具一键修复。成功启动后,需要重新安装linux-generic等元包,重建initramfs并更新

突围 1209

JVM内存区域分为哪些部分?各自的作用?

通过以上划分,JVM实现了高效的内存管理与线程隔离,为Java程序的稳定运行提供了基础保障。

破损的天堂鸟博客 1121

第五天 Labview数据记录(5.4 EXCEL文件读写)

Excel 文件读写在数据处理、自动化办公、数据分析等领域具有重要的意义。以下是 Excel 文件读写的主要应用场景和意义:1. 数据管理和整理;2. 自动化办公;3. 数据分析和可视化;4. 系统集成;5. 报表生成;6. 教育和培训;7. 实际应用场景。Excel 文件读写的意义在于提高数据处理的效率、减少人工操作、支持自动化办公、促进数据分析和可视化,以及实现系统之间的数据交互。无论是企业、组织还是个人,都可以通过 Excel 文件读写实现数据的高效管理和利用。

weixin_38637405的博客 1261

芒果YOLOv8改进160:姿态估计Head篇:即插即用|轻量化非对称多级压缩LOADH旋转检测头,原创改进适配YOLOv8高效检测头,检测头新颖改进,全网首发独一份

芒果YOLOv8改进159:OBB旋转检测头Head篇:即插即用|轻量化非对称多级压缩LOADH旋转检测头,原创改进适配YOLOv8高效检测头,检测头新颖改进,全网首发独一份

包括YOLOv5、YOLOv7、YOLOv8等模型改进 810

JVM笔记1--Java内存区域

无论是从父类继承下来的还是子类中定义的字段都必须记录下来。这部分的存储顺序会受到虚拟机分配策略参数(-XX:FieldsAllocationStyle参数)和字段在Java源码中定义的顺序有关。HotSpot虚拟机默认的分配顺序为:longs/doubles、ints、shorts/chars、bytes/booleans、oops,从以上默认分配策略中可以看到,相同宽度的字段总是被分配到一起。在满足这个条件的情况下,在父类中定义的字段会出现子类之前。

qq_41056506的博客 1168

微信小程序 - 最新详细实现气泡菜单功能,点击任意元素在底部或附近周围弹出气泡菜单列表,仿微信气泡弹框显示菜单快捷功能收纳,自定义气泡弹窗/菜单气泡弹窗,小程序气泡框嵌套菜单组件插件,自动计算弹出定位

微信小程序,vue2,vue3,气泡列表,汽泡菜单,气泡框,泡泡框,悬浮框,悬浮菜单,点击菜单按钮弹出气泡,对话箭头气泡框,弹出的气泡准确定位并吸附在附近,弹出式气泡,弹窗菜单,气泡自定义HTML弹窗,带三角的气泡弹框,三角气泡框里面嵌套菜单,当点击一个按钮或元素时,会从附近弹出一个小气泡一样的菜单列表,自定义气泡框内的内容,点击一个元素在附近弹出一个气泡弹框功能效果,气泡弹框不准怎么办,被盖住了,挡住了,长按弹出,组件插件,微信,自定义气泡菜单组件,气泡弹出框,小程序自定义气泡框,菜单气泡,包裹列表的三角

🏆 前端领域优质创作者 3915

Java面试必备:JVM内存区域的划分

Java虚拟机(JVM)是Java程序运行的核心环境,它负责管理程序的内存、执行字节码以及处理垃圾回收等任务。理解JVM的内存区域划分对于编写高效、稳定的Java程序至关重要。本文将详细介绍JVM的内存区域划分,并通过流程图帮助读者更好地理解这些概念。

qq_58299462的博客 934

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

JVM内存区域划分 Java8 和 Java21区别

Java 8的内存模型以堆、方法区、栈为核心,适合传统应用,但需要手动调优(如 GC、元空间大小)。Java 21在内存管理上更现代化:低延迟 GC(ZGC/Shenandoah)和虚拟线程减少停顿和内存占用。元空间和字符串常量池优化降低 OOM 风险。FFM API提供更安全的本地内存访问。建议追求低延迟、高吞吐量应用可升级到 Java 21,使用 ZGC 和虚拟线程。遗留系统仍可基于 Java 8,但需关注元空间和堆内存调优。

谢文峰的博客 1350

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

JAVA JVM的内存区域划分

JVM内存区域分为线程私有和共享两部分。线程私有包括:程序计数器(记录字节码行号,不会OOM)、虚拟机栈(存储方法调用信息,可能栈溢出)和本地方法栈(支持native方法)。线程共享区域有堆(存放对象实例)和方法区(存储类信息等,Java8后改为Metaspace)。堆外内存指直接内存。程序计数器不会OOM因其占用固定极小空间,仅存储行号。栈溢出发生在深度过大时,而堆是JVM最大的内存区域,几乎所有对象实例都在此分配。(149字)

best_virtuoso的博客 459

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

【JAVA】JVM 内存区域的划分

通常可以把 JVM 内存区域分为下面几个方面,其中,有的区域是以线程为单位,而有的区域则是整个 JVM 进程唯一的。首先,程序计数器在 JVM 规范中,每个线程都有它自己的程序计数器,并且任何时间一个线程都只有一个方法在执行,也就是所谓的当前方法。程序计数器会存储当前线程正在执行的 Java 方法的 JVM 指令地址;或者,如果是在执行本地方法,则是未指定值(undefined)。第二,Java 虚拟机栈(Java Virtual Machine Stack),早期也叫 Java 栈。

m0_57042151的博客 175

java面试-JVM内存区域划分

JVM内存划分 说到Java内存区域,刚开始接触java的人会下意识说出“堆栈”。这里要明确堆栈不是一个概念,而是两个概念,堆和栈是两块不同的内存区域,简单理解的话,堆是用来存放对象而栈是用来执行程序的。其次,堆内存和栈内存的这种划分方式比较粗糙,这种划分方式只能说明大多数程序员最关注的、与对象内存分配关系最密切的内存区域是这两块,Java内存区域的划分实际上远比这复杂。对于Java程序员来说,在虚拟机自动内存管理机制的帮助下,不再需要为每一个new操作去配对delete/free代码,不容易出现内存泄露

zhttly的博客 246

java jvm内存地址_JVM的内存区域划分

JVM的内存区域划分学过C语言的朋友都知道C编译器在划分内存区域的时候经常将管理的区域划分为数据段和代码段,数据段包括堆、栈以及静态数据区。那么在Java语言当中,内存又是如何划分的呢?由于Java程序是交由JVM执行的,所以我们在谈Java内存区域划分的时候事实上是指JVM内存区域划分。在讨论JVM内存区域划分之前,先来看一下Java程序具体执行的过程:如上图所示,首先Java源代码文件(.ja...

weixin_39690963的博客 86

java jvm内存地址_【java】JVM的内存区域划分

学过C语言的朋友都知道C编译器在划分内存区域的时候经常将管理的区域划分为数据段和代码段,数据段包括堆、栈以及静态数据区。那么在Java语言当中,内存又是如何划分的呢?由于Java程序是交由JVM执行的,所以我们在谈Java内存区域划分的时候事实上是指JVM内存区域划分。在讨论JVM内存区域划分之前,先来看一下Java程序具体执行的过程:如上图所示,首先Java源代码文件(.java后缀)会被Jav...

weixin_39996141的博客 130

Java中JVM的内存区域划分

JVM的内存区域划分 Java程序交由JVM(Java Virtual Machine)执行的,因此下面讨论JVM内存区域划分; 一、Java程序执行过程 Java源代码(.java)被Java编译器编译成字节码文件(.class),再由JVM中的类加载器加载各个类的字节码文件,加载完毕后交由JVM执行引擎执行。 整个程序执行过程中,JVM会用一段空间存储程序执行期间所用的

少点套路,多点诚意 531

JAVA基础面试题:Java中的JVM内存区域划分与垃圾回收算法详解

张总:"Victor,你的回答非常全面,既有理论深度,又有实际经验。看来你对JVM的理解非常透彻。Victor张总:"今天的面试就到这里,期待与你共事!Victor:"我也很期待!

Victor_119的博客 1029

【Java面试笔记:进阶】25.谈谈JVM内存区域的划分,哪些区域可能发生OutOfMemoryError?

内存区域触发条件错误信息堆(Heap)对象过多或内存泄漏方法区(Metaspace)类加载过多或动态生成类虚拟机栈线程过多或栈帧过深本地方法栈Native方法调用栈溢出(较少见)直接内存堆外内存分配过多。

2025博客之星Top81。专注AI工程化与架构实战。从分布式思维到模型部署,用工程化视角为你厘清AI落地的真实路径。 1470

Java内存区域划分(JVM运行时数据区)

我们在谈Java内存区域的划分时,事实上指的就是JVM内存区域的划分。在了解JVM内存之前,先看一下Java程序具体的执行过程。 如上图所示,首先Java源代码文件(.java后缀)会被Java编译器编译为字节码文件(.class后缀),然后由JVM中的类加载器加载各个类的字节码文件,加载完毕之后,交由JVM执行引擎执行。在整个程序执行过程中,JVM会用一段空...

Symon的博客 449

java 虚拟机内存区域_JVM中的五大内存区域划分详解及快速扫盲

一、快速扫盲1. JVM是什么JVM是JavaVirtualMachine的缩写,即咱们经常提到的Java虚拟机。虚拟机是一种抽象化的计算机,有着自己完善的硬件架构,如处理器、堆栈等,具体有什么咱们不做了解。目前我们只需要知道想要运行Java文件,必须先通过一个叫javac的编译器,将代码编译成class文件,然后通过JVM把class文件解释成各个平台可以识别的机器码,最终实现跨平台运行代码。2...

weixin_29274337的博客 971

【Java】JVM 内存区域划分

这些内存区域共同协作,支撑Java程序的运行,每个区域都有其特定的职责和生命周期管理机制。本地方法栈 Native Method Stack。局部变量表 Local Variables。年轻代 Young Generation。JDK 1.7: 永久代 PermGen。动态链接 Dynamic Linking。方法区 Method Area。Survivor 区: 20%方法区 Method Area。栈帧 Stack Frame。当前线程执行的字节码行号。Eden 区: 80%类版本/字段/方法信息。

唐古的博客 817
上一篇: Java - Lombok介绍、使用、工作原理、优缺点
下一篇: Java - JVM内存模型及GC(垃圾回收)机制
「已注销」
博客等级 码龄5年 413粉丝 46原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值