JVM中的堆和栈到底存储了什么?

2023-05-16

以下文章来自:https://www.jianshu.com/p/8a89fb6d839c,这篇文章涉及多方面知识,所以我在有些地方插入了一些更加深入的文章(方法和函数区别、指针变量、修改引用的值 与 修改引用、函数参数:形参和实参的区别)

JVM数据区

先上一张Java虚拟机运行时数据区中堆、栈以及方法区存储数据的概要图,如下所示:

然后我们来具体解析一下堆和栈

堆是存储时的单位,对于绝大多数应用来说,这块区域是 JVM 所管理的内存中最大的一块线程共享,主要是存放对象实例和数组。

栈是运行时的单位,Java 虚拟机栈,线程私有,生命周期和线程一致。描述的是 Java 方法执行的内存模型:每个方法在执行时都会创建一个栈帧(Stack Frame)用于存储局部变量表(形参也是局部变量)、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至执行结束,就对应着一个栈帧从虚拟机栈中入栈到出栈的过程。

局部变量表:存放了编译期可知的各种基本类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference 类型)和 returnAddress 类型(指向了一条字节码指令的地址)

堆和栈的对比

一、解决程序的运行问题,即程序如何执行,或者说如何处理数据;解决的是数据存储的问题,即数据怎么放、放在哪儿。

二、栈因为是运行单位,因此里面存储的信息都是跟当前线程相关的信息。包括:局部变量(含形参)、程序运行状态、方法返回值等等;而堆只负责存储对象信息。

三、在方法中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配(这一句里面的方法和函数感觉有点不对,方法和函数区别)。堆内存用于存放由new创建的对象和数组

四、在Java中一个线程就会相应有一个线程栈与之对应,这点保证了程序的并发运行。

堆则是所有线程共享也可以理解为多个线程访问同一个对象,比如多线程去读写同一个对象的值

五、栈内存溢出包括StackOverflowError和OutOfMemoryError。StackOverflowError:线程请求的栈深度大于虚拟机所允许的深度。OutOfMemoryError:如果虚拟机栈可以动态扩展,而扩展时无法申请到足够的内存

堆内存溢出是OutOfMemoryError。如果堆中没有内存完成实例分配,并且堆也无法再扩展时,抛出OutOfMemoryError异常

代码分析

最后,借助网上看到的一个例子帮助对栈内存,堆内存的存储进行理解:

对于以上这段代码,date为局部变量,i,d,m,y都是形参为局部变量,day,month,year为成员变量。下面分析一下代码执行时候的变化:

1. main

方法开始执行:int date = 9;

date:局部变量,基础类型,引用和值都存在栈中

2. Test test = new Test();

test:为对象引用,存在栈中对象(new Test())存在堆中

3. test.change(date);

调用change(int i)方法,i为局部变量,引用和值存在栈中。当方法change执行完成后,i就会从栈中消失。

上图中i→1234,我就想是不是date→1234,所以就去查了一下文章,函数参数:形参和实参的区别,修改引用的值 与 修改引用

4. BirthDate d1= new BirthDate(7,7,1970);

调用BIrthDate类的构造函数生成对象。

d1为对象引用,存在栈中;对象(new BirthDate())存在堆中;

其中d,m,y为局部变量存储在栈中,且它们的类型为基础类型,因此它们的数据也存储在栈中;

day,month,year为BirthDate对象的的成员变量,它们存储在堆中存储的new BirthDate()对象里面(对象存放在堆中等待垃圾回收)

当BirthDate构造方法执行完之后,d,m,y将从栈中消失。

5.main方法执行完之后。

date变量,test,d1引用将从栈中消失;

new Test(),new BirthDate()将等待垃圾回收器进行回收。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JVM中的堆和栈到底存储了什么? 的相关文章

  • 如何减少Scala中创建的对象数量?

    我正在 Scala 中编写一个计算机图形应用程序 它使用 RGB 类返回图像中某个点的颜色 正如你可以想象的 返回颜色 RGB 对象的函数被调用了很多次 class RGB val red Int val green Int val blu
  • 在intellij中为java启用ssl调试

    从我的问题开始 上一期尝试通过 tls ssl 发送 java 邮件 https stackoverflow com questions 39259578 javamail gmail issue ready to start tls th
  • Intellij Idea 使用什么 JVM 来启动?

    我是 Eclipse 用户 最近决定尝试 Intellij Idea 我的操作系统是 Ubuntu 12 使用 Eclipse 时 可以通过在 eclipse ini 中指定来轻松选择用于启动 Eclipse 的 JVM http wiki
  • Java GuardedString - 用于加密的随机密钥是否存储在 Java 堆内存中?如果不是,那么密钥保存在哪里?

    Oracle 的 org identityconnectors common security GuardedString 要转换为 GuardedString 的原始数据需要由 EncryptorImpl class 随机生成的加密密钥
  • 强制jvm返回本机内存[重复]

    这个问题在这里已经有答案了 我时不时地运行需要大量内存的 eclipse 任务 因此 当任务运行时 jvm 会消耗大约 2 3GB 的 RAM 这是可以的 但是一旦 jvm 占用了该内存 它就不会释放它 并且我遇到了一种情况 堆中已用内存约
  • Scala REPL 中的递归重载语义 - JVM 语言

    使用 Scala 的命令行 REPL def foo x Int Unit def foo x String Unit println foo 2 gives error type mismatch found Int 2 required
  • Bipush 在 JVM 中如何工作?

    我知道 iload 接受整数 1 到 5 但是如何使用 bipush 指令扩展到更高的数字 特定整数如何与字节码一起存储 有几种不同的指令可用于推送整数常量 最小的是iconst 指令 这些只是一个字节 因为该值是在操作码本身中编码的 ic
  • Java:为什么它使用固定数量的内存?或者它如何管理内存?

    JVM 似乎使用了一些固定数量的内存 至少我经常看到参数 Xmx 对于最大尺寸 和 Xms 对于初始大小 这表明 我感觉 Java 应用程序不能很好地处理内存 我注意到一些事情 即使一些非常小的示例演示应用程序也会加载大量内存 也许这是因为
  • Java 中清除嵌套 Map 的好方法

    public class MyCache AbstractMap
  • 通过SOCKS代理连接Kafka

    我有一个在 AWS 上运行的 Kafka 集群 我想用标准连接到集群卡夫卡控制台消费者从我的应用程序服务器 应用程序服务器可以通过 SOCKS 代理访问互联网 无需身份验证 如何告诉 Kafka 客户端通过代理进行连接 我尝试了很多事情 包
  • jvm 次要版本与编译器次要版本

    当运行使用具有相同主要版本但次要版本高于 JVM 的 JDK 编译的类时 JVM 会抛出异常吗 JDK 版本并不重要 类文件格式版本 http blogs oracle com darcy entry source target class
  • JVM:是否可以操作帧堆栈?

    假设我需要执行N同一线程中的任务 这些任务有时可能需要来自外部存储的一些值 我事先不知道哪个任务可能需要这样的值以及何时 获取速度要快得多M价值观是一次性的而不是相同的M值在M查询外部存储 注意我不能指望任务本身进行合作 它们只不过是 ja
  • Java的-XX:+UseMembar参数是什么

    我在各种地方 论坛等 看到这个参数 并且常见的答案是它有助于高并发服务器 尽管如此 我还是找不到 sun 的官方文档来解释它的作用 另外 它是Java 6中添加的还是Java 5中存在的 顺便说一句 许多热点虚拟机参数的好地方是这一页 ht
  • 线程上下文类加载器和普通类加载器的区别

    线程的上下文类加载器和普通类加载器有什么区别 也就是说 如果Thread currentThread getContextClassLoader and getClass getClassLoader 返回不同的类加载器对象 将使用哪一个
  • JVM锯齿状空闲进程

    我目前正在进行一项涉及 JVM 及其内存使用工作原理的研究 我不明白的是 JVM在空闲时用什么填充它的内存 只是为了在堆几乎达到时释放它 为什么使用的内存不只有一条平线 顺便说一句 这个 java 应用程序托管在 glassfish 上 但
  • 如何制作.Net或JVM语言?

    我看到了 NET 和 JVM 的所有这些新语言 一个人如何开始制作一个 我找不到关于 JVM 或 MSIL 规范的任何好的文档 Edit 我已经知道如何解析 我更感兴趣的是如何有这么多人基于这些平台创建新语言 你有点幸运 为 NET 开发的
  • 是什么让热部署成为“难题”?

    在工作中 我们经常遇到这样的问题 永久代内存不足 http www jroller com agileanswers entry preventing java s java lang例外 团队负责人认为这是 JVM 中的一个错误 与代码的
  • 是否有一种轻量级方法可以在 Java 9+ 中添加安全点

    Java 9 中是否有更便宜的方法调用可以保持其安全点 JVM 在运行时删除安全点以提高效率 但这可能会使分析和监视代码变得更加困难 为此 我们特意添加了一些简单的调用精心挑选确保存在安全点的地方 public static void sa
  • 如何将 JVM 选项传递给 SBT 以在运行应用程序或测试用例时使用?

    我想在运行我的应用程序或通过 SBT 对应用程序进行测试时指定 JVM 选项 具体来说 我需要能够为 JVM 提供 Djava security policy 参数 以便加载我的策略并用于测试 我怎样才能用 SBT 做到这一点 With x
  • Java 比 Xmx 参数消耗更多内存

    我有一个非常简单的 Web 服务器类 基于 Java SEHttpServer class 当我使用此命令启动编译的类来限制内存使用时 java Xmx5m Xss5m Xrs Xint Xbatch Test 现在如果我使用检查内存top

随机推荐

  • Linux buffer/cache介绍

    free 命令 与 buffer cache 在 Linux 系统中 xff0c 我们经常用 free m命令来查看系统内存的使用状态 xff1a m 显示单位为MB free m 各个参数的说明 total 内存总数 used 已经使用的
  • 数字签名算法RSA

    RSA RSA数字签名算法源于RSA公钥密码算法的思想 xff0c 将RSA公钥密码算法按照数字签名的方式运用 RSA数字签名算法是迄今为止应用最为广泛的数字签名算法 RSA数字签名算法的实现如RSA加密算法一致 RSA数字签名算法主要可分
  • AXI接口协议详解-AXI总线、接口、协议

    转自 xff1a https cloud tencent com developer article 1695010 AXI接口协议详解 AXI总线 接口 协议 AXI 总线 上面介绍了AMBA总线中的两种 xff0c 下面看下我们的主角
  • USB主机是如何检测到设备的插入的呢?

    转自 xff1a https www cnblogs com wangh0802PositiveANDupward archive 2013 05 06 3061241 html USB设备的插入检测机制 首先 xff0c 在USB集线器的
  • 电路图中的那些类似于箭头的是什么意思?

    这个双箭头在画图软件中称为 off connect xff0c 作用是连接一个工程中的两张原理图里网络标号相同的网络 即 xff1a 这张原理图中网络标号为 PCIE20 2 REFCLKP 网络 xff0c 与其他原理图中的网络标号为 P
  • linux的socket CAN驱动介绍

    https blog csdn net linyangspring article details 27186911 在linux中 xff0c CAN总线的驱动有两种实现方式 xff1a 字符设备以及socket can驱动 Socket
  • 一文讲透Linux网络设备驱动框架及编写步骤

    https blog 51cto com u 14592069 5785977 本文阐述了网络架构模型 xff0c 特别是Linux系统中网络子设备框架4层结构 xff0c 反别阐述了各层的作用 重点讲解了sk buff及net devic
  • linux下的项目管理工具make和git的使用

    在linux下我们不能向在windows下这样去快速的进行编译 xff0c 在以前我们都是使用一个命令一个命令地去将 c文件生成程序 xff0c 在这里我们介绍项目自动化辅助构建工具make以及项目版本管理工具git make make说白
  • list_for_each_entry()函数分析

    在Linux内核源码中 xff0c 经常要对链表进行操作 xff0c 其中一个很重要的宏是list for each entry xff1a span class token comment list for each entry iter
  • 电力系统谐波分析

    加粗样式 电力系统谐波分析 一 实验目的 1 了解电力系统谐波信号的特点及分析方法 xff1b 2 综合利用数字信号处理技术实现对电力系统谐波信号的分析 xff1b 3 使学生进一步巩固数字滤波器的基本概念 理论 分析方法和实现方法 xff
  • 电力系统谐波分析代码

    程序清单 xff08 1 xff09 模拟谐波的信号的波形及频谱 fs 61 3000 采样频率 N1 61 256 采样点数 N2 61 1024 n1 61 0 N1 1 t 61 n1 fs x1 61 sin 2 pi t 50 4
  • range() 函数用法

    range 函数可创建一个整数列表 xff0c 一般用在 for 循环中 函数语法 xff1a range start stop step 参数说明 xff1a start 计数从 start 开始 默认是从 0 开始 例如range xf
  • set()函数用法

    python内置函数 文章目录 python内置函数描述set 语法返回值 实例 描述 set xff08 xff09 是集合的一种 set 函数创建一个无序不重复元素集 xff0c 可进行关系测试 xff0c 删除重复数据 xff0c 还
  • pop()函数的用法

    pop 函数用于移除列表中的一个元素 xff08 默认最后一个元素 xff09 xff0c 并且返回该元素的值 语法 xff1a list pop obj 61 list 1 默认为 index 61 1 xff0c 删除最后一个列表值 o
  • python assert()函数

    1 断言函数作用 断言函数是对表达式布尔值的判断 xff0c 要求表达式计算值必须为真 可用于自动调试 如果表达式为假 xff0c 触发异常 xff1b 如果表达式为真 xff0c 不会报错 2 使用assert判断数组是否相等 np ar
  • torch.nn 实现上采样——nn.Upsample

    CLASS torch nn Upsample span class token punctuation span size span class token operator 61 span None span class token a
  • ubuntu用命令行清空回收站的方法

    1 打开Trash span class token builtin class name cd span local share Trash 2 查看Trash里的文件 span class token function ls span
  • ubuntu命令行重启

    重启命令 xff1a 法一 xff1a span class token function reboot span 法二 xff1a span class token function shutdown span r now span cl
  • Linux下的重要目录/proc, /sys, /SElinux, /bin, /usr/lib, /usr/local, /var, /tmp

    今天我们简单的介绍一些linux下面的一些重要文件夹的重用 proc 是个虚拟文件系统 也就是 重新引导后修改会被重新初始化 提供了进程信息 内存资源 硬件设备 内核内存等信息 比如 xff1a 网卡 xff1a proc sys vm i
  • JVM中的堆和栈到底存储了什么?

    以下文章来自 xff1a https www jianshu com p 8a89fb6d839c xff0c 这篇文章涉及多方面知识 xff0c 所以我在有些地方插入了一些更加深入的文章 xff08 方法和函数区别 指针变量 修改引用的值