您的位置 首页 java

Java堆、栈、常量池、成员变量和局部变量

静态成员变量放在堆还是栈?都不是,放在方法区。

Java 内存主要分成以下几块:

  • heap 【new出来的空间和数组空间,存放对象、数组,数据不能共享】
  • 虚拟机栈( 局部变量 表、操作栈、动态连接、方法返回地址)
  • 本地方法栈(native method stack)【操作系统的本地方法所需要的空间,存放局部变量、引用】
  • 方法区(method area,也叫元数据区-Metaspace)【所有对象数据共享区域,存储静态变量和普通方法、 静态方法 、常量、 字符串常量 (严格说存放在常量池,堆和栈都有)等类信息,说白了就是保存类的模板】
  • 程序 寄存器 (program counter register)【速度最快且空间最小的一块区域,由编译器分配,我们对此没有直接的控制权】

注:方法区(元数据区)是一个独立区域,既不属于堆,也不属于栈,在类加载的时候只运行一次。

JVM 内存布局-具体如下图所示:

Java 应用运行时使用的全部存储类型

  • 寄存器:最快的存储区,由编译器根据需求进行分配,我们在程序中无法控制。
  • 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放在常量池中)。
  • 堆:存放所有new出来的对象或数组。
  • 静态域:存放静态成员( static 定义的)。 —- 方法区
  • 常量池:存放 字符串 常量和基本类型常量(public static final)。
  • 非RAM存储:硬盘等永久存储空间。

(1) 栈中的数据大小和生命周期是可以确定的,当没有引用指向数据时,这个数据就会消失。堆中的对象 — 由垃圾回收器负责回收,因此大小和生命周期不需要确定,具有很大的灵活性。

(2) 对于字符串:其对象的引用都是存储在栈中的,如果是编译期已经创建好(直接用双引号定义的)的就存储在常量池中,如果是运行期(new出来的)才能确定的就存储在堆中。对于equals相等的字符串,在常量池中永远只有一份,在堆中有多份。

成员变量和局部变量:

成员变量 – 就是方法外部,类的内部定义的变量;

局部变量 – 就是方法或语句块内部定义的变量。局部变量必须初始化。

形式参数 是局部变量,局部变量的数据存在于栈内存中。栈内存中的局部变量随着方法的消失而消失。

成员变量存储在堆中的对象里面,由垃圾回收器负责回收。

在java中只要是成员变量,一旦它所在类被实例化后,都是放在 堆内存 的,不管它是不是基础类型。局部变量才是放在栈内存的。

文章来源:智云一二三科技

文章标题:Java堆、栈、常量池、成员变量和局部变量

文章地址:https://www.zhihuclub.com/177974.shtml

关于作者: 智云科技

热门文章

网站地图