内存中的栈(stack)、堆(heap)和方法区(method area)的用法

2023-11-29 15:57:14 浏览数 (1)

前言

通常我们定义一个基本数据类型的变量,一个对象的引用,还有就是函数调用的现场保存都使用 JVM 中的栈空间;而通过 new 关键字和构造器创建的对象则放在堆空间,堆是垃圾收集器管理的主要区域,由于现在的垃圾收集器都采用分代收集算法,所以堆空间还可以细分为新生代和老生代,再具体一点可以分为 Eden、Survivor(又可分为 From Survivor 和 To Survivor)、Tenured;

栈(Stack)

栈是一种后进先出(LIFO,Last In First Out)的内存区域,主要用于存储局部变量、函数调用的返回地址以及临时数据等。当程序调用一个函数时,栈会为该函数分配一个栈帧(stack frame),用于存储函数的局部变量和其他相关信息。当函数执行完毕并返回时,其对应的栈帧将从栈中弹出。

栈的主要优点是访问速度快,因为它遵循固定的内存布局。然而,它的缺点是空间受限,无法动态扩展。

栈空间操作起来最快但是栈很小,通常大量的对象都是放在堆空间,栈和堆的大小都可以通过 JVM的启动参数来进行调整,

栈空间用光了会引发 StackOverflowError,而堆和常量池空间不足则会引发 OutOfMemoryError

eg:

代码语言:javascript复制
String str = new String("hello");

上面的语句中变量 str 放在栈上,用 new 创建出来的字符串对象放在堆上,而"hello”这个字面量是放在方法区的。

堆(Heap)

堆是一种用于存储动态分配的内存数据的区域。在编程中,通过使用内存分配函数(如 C 语言中的 malloc() 或 Java 中的 new),可以在堆中动态地分配内存。堆的主要优点是可以根据需要动态扩展内存,但它的缺点是访问速度相对较慢,因为它需要进行内存管理和查找。

堆还包括一种称为“自由存储区”或“空闲存储区”的内存区域,用于存储未使用的内存块。这些内存块可以在需要时被重新分配。

方法区(Method Area)

方法区(Method Area)是 Java 虚拟机(JVM)中的一个内存区域,用于存储已加载类的元数据、静态变量、常量池和编译后的代码等。方法区是 JVM 的一个关键组成部分,它为 JVM 提供了关于已加载类的结构信息、类变量和方法代码等。

方法区的主要功能包括:

  • 存储已加载类的元数据(例如类名、访问修饰符、父类等)。
  • 存储已加载类的静态变量。
  • 存储已加载类的常量池。
  • 存储已加载类的编译后的字节码。

请注意,方法区在 Java 虚拟机规范中也被称为“永久代(PermGen)”。在 Java 8 之后,由于引入了元空间(Metaspace),永久代被弃用,元空间取而代之。

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

0 人点赞