Java 栈内存和堆内存和方法区超全讲解

本文详细介绍了Java内存管理的三个关键区域:栈内存、堆内存和方法区。栈内存存储基本类型、对象引用和方法调用,线程私有,非垃圾回收;堆内存用于存储对象,线程共享,由GC管理;方法区存储类信息、常量和静态变量。栈内存中的数据共享但线程私有,堆内存则线程共有,以避免频繁调整内存大小。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


本片博文本来是打算写一篇关于栈内存和堆内存的博文,也相当于自己的一个学习记录,结果一不小心学多了…就一直写到了内存的讲解了,本来还写了寄存器和一些硬件存储的,结果篇幅太大了就先删掉了,这里就先说下内存好了o(  ̄︶ ̄)o, 文中肯定有许多有问题不足的地方,需要各位网友大大们评论补充!

内部存储器(Internal Storage)

1.线程私有存储区(Thread-Private Storage)

1.1 栈内存(Stack)

                 /|————————————————|\
            栈 /  |____局域变量区____|  \
            帧 \  |_____操作数区_____|    \
           /     \|_____帧数据区_____|      \
         /                                   \
       /          |—————————————————|          \  <_________________________>\
 栈  /            |____局域变量区_____|            \<_______PC Register_______> \包含寄存器的
 内存\            |_____操作数区______|            /<________JVM Stack________> /单线程内存区
       \          |_____帧数据区_____|          /  <___Native Method Stack___>/
         \                                   /
           \      |—————————————————|      /
             \    |____局域变量区____|    /
               \  |_____操作数区_____|  /
                 \|_____帧数据区_____|/

  • 存储类型

    1.基本数据类型 2.对象的引用 3.方法的调用

  • 共享机制

    栈内数据共享,但线程私有

  • 作用时期

    在代码运行时,每当调用一个方法,都在在栈内存中创建一个栈内存块(栈帧),方法结束后栈内存变成未使用的状态

  • 描述

    存储基本数据类型以及对象的引用,当在一个代码块中定义一些变量的时候,栈内存中为这些变量分配空间,按照 FILO 的原则,当代码块结束时,JVM 会自动释放分配的空间。栈内存不是 GC 回收的,堆内存是的。它是由编译器自动分配和释放。可能会抛出 OutOfMemoryErrorStackOverFlowError 异常。它的存取速度很快仅次于寄存器,与堆内存相比较栈内存大小很小。可用 -Xss JVM 的选项来定义栈内存大小

  • 特点

    存取速度很快,比堆要快,速度仅次于寄存器,存在栈中的数据有明确的生存周期和数据大小。存储其中数据可共享,线程私有

  • 一些问题

    1. 栈内存存储方法的调用怎么理解?

      答:如f1()方法,其中调用了f2()方法,那么栈内存中最下层是f1(),再上面是f2()

    2. 栈内存存储对象的引用怎么理解?

      答:栈中保存的是对象的引用,该引用指向的是堆内存中对象中的数据。对象的引用是指向一个已创建的对象或者null,其只能是唯一指向,对象的引用某一时刻只能有唯一指向,对象本身可以同时被多个引用变量引用

    3. 栈内存如何存储数组?

      答:和对象存储一致

    4. 什么叫做栈中数据是共享的?

      答:假如有有如下代码

      int a = 1;
      int b = 1;
      

      java 编译器先处理a = 1,栈中会去找有没有值是 1 的空间,若有将 a 的引用直接指向这个空间,没有就在栈中开辟一个空间存储 1,然后执行b = 1,这时候直接让 b 的引用指向 a 指向的空间,这样 a 和 b 的引用指向同一个空间,但对象实际上是不同的,因为假使两个对象的引用指向的是同一个对象,如果一个对象的引用变量改变了,那么这个对象的内部状态实际上也改变了

    5. 为什么栈内存线程私有?

      答:栈内存不适合多线程共享(注意这和栈中数据共享是两个概念),因为若栈内存采用多线程共享,会非常凌乱

    6. StackOverFlowErrorOutOfMemoryError区别?

      答:StackOverFlowError栈溢出是单个线程请求栈内存大于虚拟机允许内存时候报出的,而OutOfMemoryError内存溢出是指整个虚拟机内存耗尽,无法再申请新的内存时候报出

    7. 堆内存由 GC 管控,那栈内存回收呢?为什么没用 GC 管控?

      答:栈内存也是 JV

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

abcnull

您的打赏是我创作的动力之一

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值