Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么删除了私有包字符串构造函数(int,int,char[])?_Java_String_Memory Leaks - Fatal编程技术网

Java 为什么删除了私有包字符串构造函数(int,int,char[])?

Java 为什么删除了私有包字符串构造函数(int,int,char[])?,java,string,memory-leaks,Java,String,Memory Leaks,在Java6中,有一个包私有构造函数返回一个新字符串,并更改偏移量 643 // Package private constructor which shares value array for speed. 644 String(int offset, int count, char value[]) { 645 this.value = value; 646 this.offset = offset; 647 this.coun

在Java6中,有一个包私有构造函数返回一个新字符串,并更改偏移量

643     // Package private constructor which shares value array for speed.
644     String(int offset, int count, char value[]) {
645         this.value = value;
646         this.offset = offset;
647         this.count = count;
648     }
它在Java7中被标记为不推荐使用,在Java8中被删除。我依靠一些API反复调用
子序列
,直到遇到性能问题

深入研究代码,我发现
子序列
在Java6中使用了这个构造函数。但就目前而言,它使用另一个复制底层数组并从所需的和结束的偏移量开始,从而使其成为O(1)到O(n)的操作

替换对
子序列的有问题调用将性能提高了10倍

我想知道为什么会有这样的变化。我唯一想到的是它可能会造成潜在的内存泄漏,例如:

String veryLargeString = ....;
String target = veryLargeString.substring(0, 10);
//assume I don't need anymore veryLargeString at this point
此时,底层字符数组不能是GC,因为目标字符串仍在使用它。因此,内存中有一个大数组,但只需要它的前10个值


这是唯一好的用例还是删除此构造函数的其他原因?

是的,
String
是独立的
String
对象从不共享底层的
char[]
。这绝对是一种权衡:

  • 字符串不再需要保持偏移量和长度(每个实例保存两个字段;不是很多,但每个字符串都需要)
  • 一个小字符串不能使一个巨大的
    char[]
    保持活动状态(根据您的帖子)
  • 。。。但以前很便宜的操作现在只能创建副本

在某些用例中,以前的代码会更好地工作,而在另一些用例中,新代码会更好地工作。不幸的是,听起来你好像在第一个营地。然而,我无法想象这个决定是轻率做出的——我怀疑针对不同的常见工作负载进行了很多测试。

我认为部分想法可能是,在极少数情况下,这确实会导致问题,您可以使用自己的类包装一个
char[]
来解决这个问题。不理想,但它比追踪模糊的内存泄漏更简单。@biziclop:O(1)最简单的实现,不需要自己滚动任何东西,是
CharBuffer.wrap(string).subSequence(start,end)
,它在O(1)中产生
CharSequence
。我相信,主要的动机是最终的“共定位”
字符串及其
字符[]
。现在,它们位于一个距离,这是缓存线的一个主要损失。如果每个
字符串
都拥有自己的
char[]
,JVM可以将它们合并在一起,读取速度会快得多。