Java创建对象的内存分配

  • Post author:
  • Post category:java



  • 运行时数据区域划分

JDK 1.8之前分为:线程共享(Heap堆区、Method Area方法区)、线程私有(虚拟机栈、本地方法栈、程序计数器)

JDK 1.8之后分为:线程共享(Heap堆区、Meta space元空间)、线程私有(虚拟机栈、本地方法栈、程序计数器)


  • 堆(Heap)

是被线程共享的一块内存区域,

创建对象和数组都保存在Java堆内存中,也是垃圾收集器进行垃圾收集的最重要的内存区域

。由于JVM采用

分代收集算法

,因此Java堆从GC角度还可以细分为:

新生代

(Eden区、From区、To区)和

老年代


新生代:

用来存放新生的对象。一般占用堆得1/3空间。由于频繁的创建对象,所以新生代会频繁触发MinorGC进行垃圾回收。新生代又分为Eden、From、To三个区


老年代:

主要存放应用程序中生命周期较长的内存对象。一般占用堆得2/3空间。老年代的对象较为稳定,所以MajorGC不会频繁执行


  • 创建对象的内存分配

创建一个新对象,在堆中的分配内存。

大部分情况下,对象会在

Eden

区生成,当

Eden

区装填满的时候,会触发

Young Garbage Collection

,即

YGC

垃圾回收的时候,在

Eden

区实现清除策略,没有被引用的对象则直接回收。

依然存活的对象会被移送到

Survivor

区。

Survivor

区分为

From



To

两块内存区域。每次

YGC

的时候,它们将存活的对象复制到未使用的

Survivor

空间(

From或To

),然后将当前正在使用的空间完全清除,交换两块空间的使用状态。每次交换时,对象的年龄会加

+1

如果

YGC

要移送的对象大于

Survivor

区容量的上限,则直接移交给老年代。一个对象也不可能永远呆在新生代,在

JVM

中 一个对象从新生代晋升到老年代的阈值默认值是

15

,可以在

Survivor

区交换 14 次之后,晋升至老年代。



版权声明:本文为apple_52149279原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。