Java的字符串常量池位于哪里,堆或堆栈?

转载自: https://www.baeldung.com/java-string-constant-pool-heap-stack

1.简介

每当我们声明一个变量或创建一个对象时,它就会存储在内存中。在较高的级别上,Java将内存分为两个块:stackheap两种存储器均存储特定类型的数据,并且具有不同的存储和访问模式。

2.字符串常量池

该字符串常量池是一个特殊的存储区。**当我们声明String时,JVM在池中创建对象并将其引用存储在堆栈中。**在内存中创建每个String对象之前,JVM执行一些步骤来减少内存开销。

字符串常量池在其实现中使用HashMap。HashMap的每个存储桶包含具有相同哈希码的String列表。在Java的早期版本中,池的存储区域是固定大小的,并且通常会导致*“无法为对象堆保留足够的空间”* 错误。

**当系统加载类时,所有类的*String*文字都将进入应用程序级池。**这是因为不同类的相等String文字必须是相同的Object。在这些情况下,池中的数据应可用于每个类而没有任何依赖关系。

通常,堆栈存储短期的数据。它包括局部基本变量,堆对象的引用以及执行中的方法。堆允许动态分配内存,在运行时存储Java对象和JRE类。

堆允许全局访问,并且在应用程序的生存期内,堆中的数据存储可用于所有线程,而堆栈上的数据存储具有私有作用域,只有所有者线程可以访问它们。

堆栈将数据存储在连续的存储块中,并允许随机访问。如果类需要池中的随机String,则由于堆栈的LIFO(后进先出)规则,该类可能不可用。相反,堆会动态分配内存,并允许我们以任何方式访问数据。

假设我们有一个由不同类型的变量组成的代码段。堆栈将存储int文字的值以及String和Demo对象的引用*。任何对象的值都将存储在堆中,所有String*文字都放入堆中的池中:

线程完成执行后,将立即释放在堆栈上创建的变量。相反,垃圾收集器回收堆中的资源。同样,垃圾收集器从池中收集未引用的项目。

**池的默认大小在不同平台上可能会有所不同。**无论如何,它仍然比可用堆栈大小大得多。在JDK 7之前,该池是permgen空间的一部分,从JDK 7到现在,它是主堆内存的一部分。

3.结论

在这篇简短的文章中,我们了解了String常量池的存储区域。堆栈和堆具有不同的特性来存储和访问数据。从内存分配到其访问和可用性,堆是最适合存储String常量池的区域。

实际上,池从未成为堆栈内存的一部分。

陕ICP备16008414号
使用 Hugo 构建
主题 StackJimmy 设计