内存中堆和栈的区别

内存中堆和栈的区别在说堆和栈之前 我们先说一下 JVM 虚拟机 内存的划分 Java 程序在运行时都要开辟空间 任何软件在运行时都要在内存中开辟空间 Java 虚拟机运行时也是要开辟空间的 JVM 运行时在内存中开辟一片内存区域 启动时在自己的内存区域中进行更细致的划分 因为虚拟机中每一片内存处理的方式都不同 所以要单独进行管理 JVM 内存的划分有五片 寄存器 本地方法区 方法区 栈内存 堆内存 我们重

在说堆和栈之前,我们先说一下JVM(虚拟机)内存的划分:

Java程序在运行时都要开辟空间,任何软件在运行时都要在内存中开辟空间,Java虚拟机运行时也是要开辟空间的。JVM运行时在内存中开辟一片内存区域,启动时在自己的内存区域中进行更细致的划分,因为虚拟机中每一片内存处理的方式都不同,所以要单独进行管理。

JVM内存的划分有五片:

  1. 寄存器;
  2. 本地方法区;
  3. 方法区;
  4. 栈内存;
  5. 堆内存。

我们重点来说一下堆和栈:

栈内存: 栈内存首先是一片内存区域,存储的都是局部变量,凡是定义在方法中的都是局部变量(方法外的是全局变量),for循环内部定义的也是局部变量,是先加载函数才能进行局部变量的定义,所以方法先进栈,然后再定义变量,变量有自己的作用域,一旦离开作用域,变量就会被释放。栈内存的更新速度很快,因为局部变量的生命周期都很短。

堆内存: 存储的是数组和对象(其实数组就是对象),凡是new建立的都是在堆中,堆中存放的都是实体(对象),实体用于封装数据,而且是封装多个(实体的多个属性),如果一个数据消失,这个实体也没有消失,还可以用,所以堆是不会随时释放的,但是栈不一样,栈里存放的都是单个变量,变量被释放了,那就没有了。堆里的实体虽然不会被释放,但是会被当成垃圾,Java有垃圾回收机制不定时的收取。

下面我们通过一个图例详细讲一下堆和栈:

比如主函数里的语句 int [] arr=new int [3];在内存中是怎么被定义的:

主函数先进栈,在栈中定义一个变量arr,接下来为arr赋值,但是右边不是一个具体值,是一个实体。实体创建在堆里,在堆里首先通过new关键字开辟一个空间,内存在存储数据的时候都是通过地址来体现的,地址是一块连续的二进制,然后给这个实体分配一个内存地址。数组都是有一个索引,数组这个实体在堆内存中产生之后每一个空间都会进行默认的初始化(这是堆内存的特点,未初始化的数据是不能用的,但在堆里是可以用的,因为初始化过了,但是在栈里没有),不同的类型初始化的值不一样。所以堆和栈里就创建了变量和实体:

在这里插入图片描述

那么堆和栈是怎么联系起来的呢?

​ 如果当int [] arr=null;

​ arr不做任何指向,null的作用就是取消引用数据类型的指向。

当一个实体,没有引用数据类型指向的时候,它在堆内存中不会被释放,而被当做一个垃圾,在不定时的时间内自动回收,因为Java有一个自动回收机制,(而c++没有,需要程序员手动回收,如果不回收就越堆越多,直到撑满内存溢出,所以Java在内存管理上优于c++)。自动回收机制(程序)自动监测堆里是否有垃圾,如果有,就会自动的做垃圾回收的动作,但是什么时候收不一定。

所以堆与栈的区别很明显

1.栈内存存储的是局部变量而堆内存存储的是实体;

2.栈内存的更新速度要快于堆内存,因为局部变量的生命周期很短;

3.栈内存存放的变量生命周期一旦结束就会被释放,而堆内存存放的实体会被垃圾回收机制不定时的回收。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/228793.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午6:11
下一篇 2026年3月16日 下午6:11


相关推荐

  • html中滚动条的代码是什么?如何设置html滚动条?

    html中滚动条的代码是什么?如何设置html滚动条?本篇文章主要介绍了关于 html 中的滚动条的代码 还有关于 html 滚动条代码 marquee 标签属性的用法 具体的让我们一起来看这篇文章吧首先我们介绍 html 中的滚动条代码 今天我们介绍这个 html 滚动条标签是 marquee marquee 标签 它是成对出现的标签 首标签 marquee 和尾标签 marquee 之间的内容就是滚动内容 marquee 标签的属性主要有 behavior bgcolor direction width height marquee marquee

    2025年7月7日
    5
  • navicat2021 7 mac激活码【2021免费激活】

    (navicat2021 7 mac激活码)这是一篇idea技术相关文章,由全栈君为大家提供,主要知识点是关于2021JetBrains全家桶永久激活码的内容IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.htmlMLZPB5EL5Q-eyJsaWN…

    2022年3月20日
    49
  • OpenClaw需求激增,10余家公司率先“养龙虾”!DeepSeek V4要来?融资客埋伏的绩优概念股出炉

    OpenClaw需求激增,10余家公司率先“养龙虾”!DeepSeek V4要来?融资客埋伏的绩优概念股出炉

    2026年3月13日
    3
  • 时间片轮转调度算法的计算

    时间片轮转调度算法的计算在分时系统中 最简单最常用的就是基于时间片轮转调度算法 时间片轮转调度算法是非常公平的处理机分配方式 让就绪队列的每个进程每次仅运行一个时间片 1 时间片轮转调度算法的基本原理 nbsp nbsp 在时间片轮转调度算法中 系统根据先来先服务的原则 将所有的就绪进程排成一个就绪队列 并且每隔一段时间产生一次中断 激活系统中的进程调度程序 完成一次处理机调度 把处理机分配给就绪队列队首进程 让其执行指令 当时间片结束

    2026年3月19日
    2
  • redis客户端连接(error) NOAUTH Authentication required「建议收藏」

    redis客户端连接(error) NOAUTH Authentication required「建议收藏」redis客户端连接成功,但是操作报异常——(error)NOAUTHAuthenticationrequired错误的含义是说你没有认证,说明没有使用密码连接查看密码:进入redis的安装目录(是安装目录的),查看redis.config文件viredis.config打开配置文件后,输入#requirepassfoobared(快速定位的命令)然后回车红框里的就是密码使用密码连接.

    2022年5月2日
    72
  • 整除计算器_0 整除

    整除计算器_0 整除原题链接这里所谓的“光棍”,并不是指单身汪啦~ 说的是全部由1组成的数字,比如1、11、111、1111等。传说任何一个光棍都能被一个不以5结尾的奇数整除。比如,111111就可以被13整除。 现在,你的程序要读入一个整数x,这个整数一定是奇数并且不以5结尾。然后,经过计算,输出两个数字:第一个数字s,表示x乘以s是一个光棍,第二个数字n是这个光棍的位数。这样的解当然不是唯一的,题目要求你输出最小的解。提示:一个显然的办法是逐渐增加光棍的位数,直到可以整除x为止。但难点在于,s可能是个非常大的数 ——

    2022年8月8日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号