Java不可变对象如何回收_java – 不可变对象的内存管理

我对于不可变对象的内存管理存在概念上的疑问,例如java和其他语言中的String对象.例如,如果我有一个String对象“str”,其值为“Hello”,我会执行以下操作:

String str = "Hello";

str = str.concatenate("World");

在这种情况下,据我所知,创建了一个状态为“Hello World”的新String对象,并将其引用回str.现在,在Java(以及大多数其他面向对象的语言)中,任何对象的生命周期都与其引用一样长.那么持有“你好”的对象去哪里了.它是否驻留在内存堆中,直到垃圾收集器自行处理它?另外,那些不支持垃圾收集器并且必须依赖于类析构函数的语言呢?

此外,如果可变对象(如StringBuffer和StringBuilder)更灵活且性能更友好,为什么在设计语言时首先使对象成为不可变的? (我的意思是为什么String Objects从一开始就不可变,而不必在后续的JDK版本中引入新的结构,如String Buffers?).

如果有人可以指导我这将是很好的.我是新手,所以一个明确的,基本的解释将受到高度赞赏.谢谢.

解决方法:

这实际上是一个关于java String类的问题 – 一般来说不是不变量.当Java首次引入时,设计人员决定使String特殊 – 在某些方面它位于引用类型和基本类型之间.

我们使用String获得的优势是虚拟机保留了一个公共的字符串文字池,阻止了堆填充 – 请参阅here以获取描述.这背后的原因是程序的大部分内存可以用于存储常用的字符串.另见String.intern.

对于任何其他类型的不可变对象,情况并非如此(遗憾的是).关于str去哪里的问题已由其他人回答 – 它遵循我确定你知道的(或可以找到)正常的垃圾收集规则.

也许你问题中最有趣的部分是

Also, if mutable objects such as StringBuffer/StringBuilder are much

more flexible and performance friendly, why make objects mutable in

the first place, while designing the language?? (I mean why aren’t

String Objects mutable right from the beginning instead of having to

introduce new structures such as String Buffers in subsequent jdk

releases?).

我的答案是,常见的情况是我们有很多相同的字符串,我们希望针对常见情况进行优化.另请注意,Java编译器在连接字符串时使用StringBuilder.例如,使用此代码

public class StringBuilderTest {

public static void main(String [] args){

String hello = "hello ";

String world = "world";

System.out.println(hello+world);

}

}

并使用它拆卸它

javap -c StringBuilderTest

并获取main方法的以下字节码

public static void main(java.lang.String[]);

Code:

0: ldc #2 // String hello

2: astore_1

3: ldc #3 // String world

5: astore_2

6: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;

9: new #5 // class java/lang/StringBuilder

12: dup

13: invokespecial #6 // Method java/lang/StringBuilder."":()V

16: aload_1

17: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

20: aload_2

21: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

24: invokevirtual #8 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;

27: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V

30: return

}

它使用StringBuilder来执行追加.

标签:java,memory-management,immutability

来源: https://codeday.me/bug/20190723/1509484.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值