问题标签 [string-pool]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
147 浏览

java - 从Java应用程序外部传递的字符串是否会保存在字符串池中?

我阅读了很多答案,但没有一个能真正准确地回答我的问题。

如果我有一个在某个端口上运行的 java 服务并且客户端连接到它并调用如下方法:

现在我的问题是,这个键(clientKey)会存储在服务端的字符串文字池中吗?通常,要存储在常量池中的文字是在编译时计算出来的,但是从 JVM 外部传递的字符串或读取文件时可能会发生什么情况?

0 投票
1 回答
338 浏览

java - 方法本地字符串内存分配?

我了解 String pool 和 intern() 方法在 java 中的工作原理。这里有一个简单的介绍。

Java 6 中的 String.intern()

在过去的美好时光里,所有的实习字符串都存储在 PermGen 中——堆的固定大小部分,主要用于存储加载的类和字符串池。除了显式嵌入的字符串之外,PermGen 字符串池还包含您程序中之前使用的所有文字字符串(这里使用了重要的词——如果从未加载/调用过类或方法,则不会加载其中定义的任何常量)。

Java 6 中这种字符串池的最大问题是它的位置——PermGen。PermGen 的大小是固定的,不能在运行时扩展。您可以使用 -XX:MaxPermSize=96m 选项进行设置。据我所知,默认 PermGen 大小在 32M 到 96M 之间变化,具体取决于平台。您可以增加它的大小,但它的大小仍然是固定的。这种限制需要非常小心地使用 String.intern——你最好不要使用这种方法来实习任何不受控制的用户输入。这就是为什么在 Java 6 时代字符串池主要是在手动管理的映射中实现的。

Java 7 中的 String.intern()

Oracle 工程师对 Java 7 中的字符串池逻辑进行了极其重要的更改——将字符串池重新定位到堆中。这意味着您不再受单独的固定大小内存区域的限制。所有字符串现在都位于堆中,就像大多数其他普通对象一样,这允许您在调整应用程序时仅管理堆大小。从技术上讲,仅此一项就足以成为重新考虑在 Java 7 程序中使用 String.intern() 的充分理由。但还有其他原因。

资源

好的,到目前为止,我对字符串在内存中的存储方式感到满意,直到我遇到这个工具Java Visualizer。我编写了以下简单的 Java 类来可视化程序中的内存分配方式。

我得到了以下结果:

展示台输出

如您所见,字符串文字和具有相同值的对象被重复并存储在堆栈中,而堆空间不会出现在方法本地字符串的图片中。起初我很困惑,但后来我搜索并发现了JDK 7 自动完成的逃逸分析。但是在我的代码中,我创建了一个 String 对象,它应该存储在堆上,但它在堆栈上,正如您在可视化器输出中看到的那样,但我的 Dummy 类对象存储在堆上。我无法真正掌握这种行为。方法本地字符串与其他对象和实例级字符串的处理方式有何不同?

0 投票
3 回答
1635 浏览

java - StringBuilder.append() 方法是否填满了字符串池?

我知道使用 String 的大多数方法将返回一个新的字符串对象,该对象将添加到字符串池中,并且作为参数传递给这些方法的字符串文字也将添加到字符串池中。

例如,下面的代码将创建三个字符串对象,即:“Hello”、““World!”和“Hello World!” 它们被添加到字符串池中,这意味着传递给 concat() 方法的参数被添加到字符串池中。

我很想知道传递给 StringBuilder.append() 方法的字符串文字参数和 StringBuilder 中的任何其他方法是否被添加到字符串池中。

或者也许我应该问是否所有传递给任何其他类中的任何其他方法的字符串文字参数也都添加到字符串池中?

我还想添加基于 java 6 的我知道的这些事实。

0 投票
1 回答
83 浏览

java - 为什么我的变量包含“2122”而不是“2322”?

这是考试中的一道题。幸运的是我选择了正确的答案,但我仍然不明白为什么它是正确的。

考虑这个程序:

它会打印出来2122。但是,我希望2322(运行代码时我显然错了)。我的理由是:

在 main 方法的第三行,D初始化了四个 get 实例。的构造函数D创建 的新实例C。的实例C有一个String变量,该变量指向内存中的某个点。现在对象的实例变量c,我们称之为它c3d[1]有一个实例变量(类型String),我们称之为它,指向与 的变量s3相同的内存。String s1c1

所以当我们改变时s1,我希望 的值s3也会改变,因为它指向内存中的同一个点。

附带说明一下,如果您更改 的构造函数D,请参见下文,您将得到2322相反的结果。这是我所期望的,因为现在变量c3ind[1]直接指向c1.

到目前为止我对解释的想法(可能是错误的):

  1. 初始化实例变量s1/s3时,会生成新String对象(到目前为止,我假设它们指向池中"1"String因为构造函数C使它看起来那样)
  2. 更改时s1,它的指针将被重定向到"3"池中String。而不是"1"成为"3"游泳池。

谁能解释这种行为?我的(错误的)推理中有什么错误?

0 投票
2 回答
166 浏览

java - Java中的字符串

我很想知道在以下情况下 String 对象行为的确切原因。

我很想了解以下代码段及其工作原理。

片段

问题:

  • 那些字符串文本,即存储在内存中的字符数组在哪里?“我属于字符串池”字符数组是否存在于字符串池中,而“我存在于堆空间”字符数组是否实际存在于堆空间中?

简而言之,谁能解释一下字符串字面量引用、字符串字面量文本、字符串对象引用s2、字符串对象文本等的存储位置。

像以下帖子这样的图表表示将非常有用。 http://theopentutorials.com/tutorials/Java/strings/string-literal-pool/

0 投票
2 回答
695 浏览

java - 在普通内存和字符串池中创建新字符串

例如:

然后,

案例1String str3 = str1.concat(str2)会进入堆还是池?

案例2String str4 = str2.concat(“HI”)会进入堆还是池?

0 投票
2 回答
136 浏览

java - 字符串内存分配和字符串池概念

在内存分配和字符串池方面,这两个分配有什么区别。

0 投票
4 回答
5126 浏览

java - Java 字符串对象创建

我一直在阅读 Java String 对象,我有这个问题 -

它会在 Java 中创建两个对象吗?

0 投票
5 回答
304 浏览

java - 字符串对象创建

假设以下是一段代码,创建了多少字符串对象以及在哪里(StringPool 或堆内存)提及指向适当对象的引用。

0 投票
4 回答
4655 浏览

java - 为什么使用 new 运算符创建的字符串会在字符串池中创建字符串文字

我的问题是,当我们将 String 声明为时,在字符串池和堆上创建字符串对象有String a = new String("abc");什么好处?

当我们将字符串创建为时,为什么不在堆中创建字符串String a = "abc"