Java面试–堆和栈的概念和区别

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

堆和栈的概念和区别【转载自博客】

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

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

      JVM内存的划分有五片:

       1.   寄存器;

       2.   本地方法区;

       3.   方法区;

       4.   栈内存;

       5.   堆内存。

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

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

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

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

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

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

                                                  Java面试--堆和栈的概念和区别

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

     我们刚刚说过给堆分配了一个地址,把堆的地址赋给arr,arr就通过地址指向了数组。所以arr想操纵数组时,就通过地址,而不是直接把实体都赋给它。这种我们不再叫他基本数据类型,而叫引用数据类型。称为arr引用了堆内存当中的实体。(可以理解为c或c++的指针,Java成长自c++和c++很像,优化了c++)                                                                Java面试--堆和栈的概念和区别

     

              如果当int [] arr=null;

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

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

             所以堆与栈的区别很明显:

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

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

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

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

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

(0)
上一篇 2026年3月18日 下午2:13
下一篇 2026年3月18日 下午2:13


相关推荐

  • 【题解】递归数列

    【题解】递归数列"题目链接"题目大意:给定序列迭代规则,求一段的序列和。特点是要求的序列很长。Solution观察到,由于是求和,我们可以想到前缀和的思想。也就是说,对于求$\sum_{i=

    2022年7月2日
    35
  • Linux下addr2line命令用法

    Linux下addr2line命令用法Linux 下 addr2line 命令用于将程序指令地址转换为所对应的函数名 以及函数所在的源文件名和行号 当含有调试信息 g 的执行程序出现 crash 时 coredumped 可使用 addr2line 命令快速定位出错的位置 如果无法确定文件名或函数名 addr2line 将在它们的位置打印两个问号 如果无法确定行号 addr2line 将打印 0 或一个问号 参数说明 1 a 在函数名 文件名和行号信息之前 以十六进制形式显示地址

    2026年3月20日
    5
  • Windows 7专业版安装VS2005与WinCE6.0开发环境

    近期更新了自己的小黑从XP更新到WIN7专业版,我花了两天时间验证了下列软件安装在WIN7PRO是完全兼容的。1:2011年最新更新的SourceInsight3.50.0066版本,这个是支持W

    2021年12月26日
    42
  • python常用函数总结

    python常用函数总结普通函数一、输入输出函数1、print()函数输出函数向屏幕输出指定的汉字print("helloworld")print()函数可以同时输出多个字符串,用逗号“,”

    2022年7月5日
    25
  • 如何解决DeepSider插件加载失败问题?

    如何解决DeepSider插件加载失败问题?

    2026年3月16日
    5
  • 区块链Baas平台纳管实战

    区块链Baas平台纳管实战因此 成熟的 BaaS 平台不仅需要具备低门槛快速建链及运维管控的能力 还要具备对已运行的异构链纳入 BaaS 平台进行统一管控的能力 下文中我们将之称为 纳管 如此一来便可以适配更多企业需求 帮助企业实现全量区块链业务的统一管控 降本增效 统一管控 可以摆脱 IT 网络环境的限制 对已在运行的异构联盟链进行不侵入式的远程纳管 从而实现无论已运行一段时间的联盟链还是 BaaS 自建的联盟链 均可以在同一平台进行统一管控和监控 挑战 2 对于非 BaaS 平台内创建的链 能不能也纳入管理

    2026年3月17日
    1

发表回复

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

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