fre*_*crs 5 java string immutability
我运行了那些代码,我得到了一些问题,这有点奇怪.
使用字符串:
while(true)
{
String s = String.valueOf(System.currentTimeMillis());
System.out.println(s);
Thread.sleep(10);
}
Run Code Online (Sandbox Code Playgroud)
使用StringBuilder:
StringBuilder s = null;
while(true)
{
s = new StringBuilder();
s.append(System.currentTimeInMillis());
System.out.println(s);
Thread.sleep(10);
}
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,他们都会陷入12540 K的内存浪费.在Windows XP SP2上运行此测试.
他们为什么浪费相同数量的记忆?为什么不可变的String会停止浪费内存?偏离主题:如何转换StringBuilder为特定字符集中编码的字节数组?
很难弄清楚你在这里问的是什么,但应用程序的行为与我期望的完全一样.
字符串是不可变的,垃圾收集器不会将它们取出.不是吗
可变和不可变对象都可以用Java进行垃圾收集.
确定对象是否实际上是垃圾收集的实际标准是可达性.简单来说,当垃圾收集器发现应用程序不能再使用对象时,该对象将被删除.
在两个应用程序中,每10毫秒创建一次大小相同的对象.在每次迭代中,正在创建一个新对象并将其引用分配给s,替换先前的引用.这使得先前的对象无法访问,并且有资格进行垃圾回收.在某些时候,Java VM决定运行垃圾收集器.这摆脱了所有无法访问的对象......应用程序继续.
我读过垃圾收集器没有收集过常见的字符串,这是假的吗?
这有两个方面是假的:
通过创建字符串new String(...),String.substring(...)1等没有从任何其他Java对象不同.
被拦截的字符串(通过调用String.intern())存储在字符串池中,该字符串池保存在PermGen堆2中.但是,即使是PermGen堆也是垃圾收集的,尽管通常在比通常创建对象的堆的时间更长的时候.
(曾几何时,PermGen堆不是垃圾收集的,但很久以前就已经改变了.)
正如@MichaelBorgwardt正确识别的那样,您将字符串对象(通常)与对应于字符串文字的字符串对象混淆.后者自动实现,最终进入字符串池.但是,他们可能仍然会收集垃圾.如果卸载父类并且没有其他任何内容引用文字,则会发生这种情况.
1 - 在Java 6及更早版本中,使用new String和使用创建的字符串之间存在差异String.substring.在后一种情况下,原始字符串和子字符串将共享保存字符串字符的后备数组.在Java 7中,这发生了变化. String.substring现在创建一个新的后备阵列.
2 - 从Java 7开始,字符串池只是普通堆中的(隐藏)数据结构.从Java 8开始,PermGen堆不再存在.
你混淆了两件非常不同的东西:
| 归档时间: |
|
| 查看次数: |
9691 次 |
| 最近记录: |