在Java中,字符串作为String类的对象存储在内存中。
在任何Java程序中分配内存时,JVM(Java虚拟机)将分配的内存分为两部分。一部分是栈,另一部分是堆。java在堆内存中分配了一些内存,特别是字面量,称为字符串常量池(SCP)。 SCP 是堆内预定义的区域。有助于字符串池 Java 节省大量空间进行操作。 String 类使用 SCP 存储唯一的字符串文本。
存储变量或变量引用或对象引用在堆栈内存中。
所有动态分配的对象都存储在堆内存中。为了将内存分配给对象,我们使用它 new 关键字。
立即学习“Java免费学习笔记(深入);
有两种方法可以创建字符串对象。
- 字符串文字
字符串 str1 = “MyString”;
每当我们创建字符串文本时,JVM 首先,检查字符串文本是否存在于字符串常量池中。如果没有,它将存在 SCP 创建一个新的字符串文本。
在上图中,str1指向SCP中的“MyString"。以下是处理新创建的字符串文本的方法。
- 使用新的关键词
String str2 = new String(“MyString”); ///使用new关键字实例化字符串类
当使用 new 当关键字创建字符串对象时,它将创建两个对象。一个 SCP 另一个在堆栈中,引用变量存储在堆栈中。
我们已经用过了
创作了“文字”MyString”字符串 str1 = “MyString”;
由于 SCP 因此,重复项中不能有重复项,因此 JVM 不会在 SCP 再创建一个对象,而是回到堆栈中的变量 str3 现有的引用,并在堆中创建一个对象。 Str3 将指向堆中的对象“MyString",但不指向 SCP 中的对象。
以下是如何为字符串对象分配内存的不同情况。
情况1:如何将上述定义的字符串对象存储在内存中。
公共字符串存储概念
{
public static void main(String[] args)
{
字符串 str1 = “MyString”;
String str2 = new String(“MyString”);
System.out.println(str1 == str2); //输出:False
System.out.println(str1.equals(str2); //输出:True
}
}
当我们使用“==”运算符比较时 str1 和 str2 时,它返回 false。众所周知,“==”运算符比较它们的物理地址。在我们的例子中,str1 指向 SCP str2中的对象 指向堆中的物体。所以它返回 false。 但在 str1.equals(str2) 正如我们所知,“equals会检查函数 str1 和 str3 每个字符是否具有相同的存储值并返回 true。
情况 2:另一个字符串文字
字符串 str3 = “MyString”;
str1 和 str3 都将指向 SCP 同一字符串在中间。
公共类字符串存储概念
{
public static void main(String[] args)
{
字符串 str1 = “MyString”;
字符串 str3 = “MyString”;
System.out.println(str1 == str2); //输出:True
System.out.println(str1.equals(str2); //输出:True
}
}
s1 == s3 返回 true,由于“==”运算符比较了它们的物理地址,但没有比较内容。 s1.equals(s3) 返回 true,“equals” 函数检查两个引用变量中的单个字符。
情况 3:用新关键字创建另一个字符串对象
String str4 = new String(“NewString”);
在这种情况下,JVM会在SCP中检查字符串,但找不到值“NewString“字符串对象,所以会创建两个对象,一个在SCP中,另一个在Heap中,引用变量str4将存储在堆栈中。 Str4 引用堆中对象。
情况 4:创建另一个字符串文本。
字符串 str5 = “NewString”;
在这种情况下,JVM 将在 SCP 检查文本是否可用,这里“NewString已存在于 SCP 中,因此 JVM 不会在 SCP 创建重复项,但返回对变量 str5 的引用。
情况 5:将一个字符串分配给另一个字符串
String str4 = new String(“NewString”);
字符串 str6 = str4; //赋值
在这里,str6和str4将指向Heap中的同一对象,不会擦除str4中的值。
公共类字符串存储概念
{
public static void main(String[] args)
{
String str4 = new String(“NewString”);
字符串 str6 = str4;
System.out.println(str4 == str6); //输出:true
}
}
JVM将堆中“JVM”NewString引用赋予变量str6。这就是 str4 == str6 返回 true 的原因。
总之,使用字符串文字和“new“运算符创建字符串对象有其优缺点。
通过使用字符串文本,我们可以通过不创建重复项来提高内存效率。 JVM 创建一个唯一的对象,字符串将永远保留在 SCP 中。这样做的缺点是字符串池的大小是固定的,有时会变满。 但通过使用 new 关键字,它创建了两个对象,一个 SCP 中间,另一个在堆里。如果我们不需要这个物体,垃圾收集器将删除这个物体以腾出空间。但这样做的缺点是使用“new”运算符,JVM 总是要创造一个新的对象,这对 JVM 它是一种重载。
以上就是Memory Allocation of Strings in 更多关于Java的详细信息,请关注图灵教育的其他相关文章!