Java中对象到底存在堆中还是栈中

探讨Java中对象的存储位置,分析基本数据类型与复杂对象在栈与堆的区别,详解Hotspot的逃逸分析技术如何决定对象的存储位置。

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

创建一个对象的时候,到底是在栈中分配还是在堆中分配需要看2个方面:对象类型和在Java中存在的位置

  • 如果是基本数据类型,byte、short、int、long、float、double、char,如果是在方法中声明,则存储在栈中,其它情况都是在堆中(比方说类的成员变量就在堆中);
  • 除了基本数据类型之外的对象,JVM会在堆中创建对象,对象的引用存于虚拟机栈中的局部变量表中
  • 并不是所有的对象都在堆中存储,可以走栈上分配,在不在栈上分配取决于Hotspot的一个优化技术:“逃逸分析”

逃逸分析中有方法逃逸和线程逃逸

  • 方法逃逸:
    就是当一个对象在方法中定义后,它可能被外部方法访问到,比如说通过参数传递到其它方法中
  • 线程逃逸:
    就是当一个对象在方法中定义后,它可能赋值给其它线程中访问的变量

如果不满足逃逸分析就会在栈上分配
栈上分配的好处就是方法出栈后内存就释放了,不需要通过gc来进行垃圾回收

需要注意的是:如果执行方法频次比较低的话,是不会触发栈上分配的

### Java的区别及用途 #### (Stack) 是一种后进先出的数据结构,在Java中主要用于存储方法调用过程中所需的信息。每当一个方法被执行时,一个新的帧会被压入顶,这个帧包含了该方法的局部变量表、操作数、动态链接和返回地址等信息。由于的操作非常简单且高效,因此其访问速度较快。 - **生命周期短**:上的数据通常只存在于当前方法的执行期间,一旦方法结束,对应的帧就会弹出并释放资源。 - **线程私有**:每个线程都有自己独立的空间,不同线程之间的互不干扰[^1]。 ```java public void exampleMethod() { int localVariable = 10; // 局部变量存放在中 } ``` #### (Heap) 相对于而言,是一片较大的内存区域,主要用来存放由`new`关键字创建的对象实例以及数组。这些对象可以在整个应用运行周期内存在,并可被多个线程共享使用。为了防止内存泄漏,JVM提供了垃圾收集机制来自动清理不再使用的对象所占据的空间。 - **生命周期长**:相比于中的临时性数据,里的对象往往具有更持久的生命期,直到没有任何引用指向它为止才会被GC回收。 - **线程共享**:所有线程都可以访问同一份区内的对象,这使得多线程协作成为可能[^4]。 ```java class ExampleClass { String instanceField; public static void main(String[] args) { ExampleClass obj = new ExampleClass(); // 对象存放在中 obj.instanceField = "This is an object on the heap"; } } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值