首页 > 其他 > 详细

JVM运行时数据区之堆和栈的介绍

时间:2021-04-06 14:56:25      阅读:20      评论:0      收藏:0      [点我收藏+]

一、JVM在运行时会将数据区划分到不同的内存区域去管理,在JVM进程运行时,会将数据分为以下区域:

1、线程私有的区域:程序计数器、本地方法栈和虚拟机栈

2、线程共有的区域:堆和方法区 

A、程序计数器:是标识当前线程执行字节码的行号计数器,是唯一不会有OUTOFMEMORY错误的区域

B、虚拟机栈:是线程私有内存,描述了Java方法执行的内存模型,在线程执行过程中,每一个方法对应一个栈帧,方法调用对应一个栈帧的入栈,方法结束对应栈帧的出栈;

C、本地方法栈:与虚拟机栈的作用类似。不同之处在于,虚拟机栈是为虚拟机执行JAVA方法,本地方法栈为虚拟机执行NATIVE方法

D、堆:是被所有线程共享的内存区域,可以存放JAVA对象及数组,在虚拟机启动时就创建。

E、方法区:也是被所有线程访问的内存区域,主要存储类信息、常量、静态变量和程序被编译后的字节码。

二、JVM运行时数据区之堆和栈的区别

JVM运行时数据区划分为堆和栈,这种设计是十分优雅的;栈是解决数据运行逻辑的问题,而堆是解决数据存储的问题;栈是数据运行时单位,堆是数据存储单位;

为什么要设置堆栈分离呢?

1、这种设计体现了分而治之的思想,堆代表了存储,栈代表了逻辑,这样逻辑更为清晰。

2、这种设计,使得堆中的数据可以被所有栈共享,一方面提供了共享内存这种有效的数据交互方式,另一方面使得堆数据和缓存可以被所有栈共享,节省空间。

3、这种设计,由于栈本身的特点,只能向上增长,限制了存储能力;而堆的对象可以动态增长,栈只需记录堆中的地址。

4、这种设计,体现了面向对象的思想;面向对象的思想,更接近自然思考的方式;而对象的属性就是数据,存放在堆中,对象的行为就是处理逻辑,放在栈中。

 

堆和栈中分别存放的内容

堆中存放的是对象、数组和基本数据类型的包装类,栈中存放的是基本数据类型和对象的引用;堆中的对象大小不固定,可以动态扩展,而栈中只存放了对象的引用,这个引用的大小是4Byte; 基本数据类型也是放在栈中存储的,由于基本数据类型的大小是固定的,占用空间不大,放在栈中不是问题;

堆和栈是程序运行最根本的东西,程序有了堆栈才可以运行;而堆栈分离,使得垃圾回收成为可能。

 

三、堆中存储对象的大小

当一个对象在堆中被创建的时候,如果只是空对象,会占有8byte的空间。

Object o = new Object();

当以上这个代码被执行后,就创建了一个新的对象,它占用的空间大小为4B+8B=12B;其中的8B是在堆中占用的空间,4B是栈中对象引用占用的空间大小。

由于非基本类型的对象都默认继承自Object,因此任何非基本类型的对象被创建后,其大小都是8B

所以当以下程序代码执行后,可以计算这个对象占用空间的大小:
Class Test{

int number;

boolean flag;

Object o;

}

空对象大小 8Bint大小 4Bboolean 大小 1B,空Object引用大小4B

这个对象被创建的大小为 17B,但是JAVA在对对象分配时是按照8的倍数来分的,因此它占用的大小为24B

基本数据类型的包装类应该被当作对象来看待,存放到堆中;包装类型的大小至少是12byte(声明一个空Object至少需要的空间),而且12byte没有包含任何有效信息,同时,因为Java对象大小是8的整数倍,因此一个基本类型包装类的大小至少是16byte。

JVM运行时数据区之堆和栈的介绍

原文:https://www.cnblogs.com/aqingsir/p/14621540.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!