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 是否将字符串封装为字节[]以节省内存过度消耗?(爪哇)_Java_String_Oop_Memory Management_Byte - Fatal编程技术网

Java 是否将字符串封装为字节[]以节省内存过度消耗?(爪哇)

Java 是否将字符串封装为字节[]以节省内存过度消耗?(爪哇),java,string,oop,memory-management,byte,Java,String,Oop,Memory Management,Byte,最近在查看一些Java Swing代码时发现: byte[] fooReference; String getFoo() { returns new String(fooReference); } void setFoo(String foo) { this.fooReference = foo.getBytes(); } 我听说,以上这些对节省你的记忆很有用 这是不是有人用这种方式封装他们的字符串?这是一个非常非常糟糕的主意。不要使用平台默认编码。如果调用setFoo,然后调

最近在查看一些Java Swing代码时发现:

byte[] fooReference;

String getFoo() {
   returns new String(fooReference); 
}

void setFoo(String foo) {
  this.fooReference = foo.getBytes();
}
我听说,以上这些对节省你的记忆很有用

这是不是有人用这种方式封装他们的字符串?这是一个非常非常糟糕的主意。不要使用平台默认编码。如果调用
setFoo
,然后调用
getFoo
,您将得到相同的数据,这是毫无疑问的

如果您必须这样做,那么请使用UTF-8,它一定可以代表整个Unicode。。。但我真的不会这么做。它可能会节省一些内存,但代价是在大部分时间内执行不必要的转换,并且容易出错,无法使用适当的编码


我敢说,在某些应用程序中,这是合适的,但对于99.99%的应用程序来说,这是一个糟糕的想法。

这并不是真正有用的:
1.每次调用getFoo或setFoo时都会复制字符串,因此会增加CPU和内存的使用量

2.它很晦涩

这很可能是过度使用,甚至可能会消耗更多内存,因为您现在有两个字符串副本。字符串的实际使用寿命取决于客户端,但与许多此类黑客一样,它闻起来很像是过早优化。

如果在分析代码之后,发现字符串的内存使用存在问题,那么最好使用通用字符串压缩器并存储压缩的字符串,而不是试图使用UTF-8字符串来减少它们提供给您的空间。对于英语字符串,通常可以将其压缩为每个字符1-2位;大多数其他语言可能都类似。进入如果您预期会有很多相同的字符串,那么另一个更好的节省内存的方法是使用该方法。

每次调用getFoo()都会实例化一个新字符串。这是如何节省内存的?如果您要为垃圾收集器增加额外的开销,以便在这些新引用未被引用时清理这些新实例,那么这确实没有任何意义。如果它是一个编译时常量,您不需要将其推回
字符串,那么它会更有意义。您仍然存在字符编码问题

如果它是一个
char[]
常量,对我来说会更有意义。在现实世界中,有几个JSP编译器可以将字符串常量优化为
char[]
,而这反过来又可以很容易地写入一个字符串。这最终会“稍微”提高效率,但在谷歌搜索等大量使用的大型应用程序中,这些小数据非常重要

Tomcat的JSP编译器也能做到这一点。检查
genstringascharray
设置。那么它就喜欢这样了

static final char[] text1 = "some static text".toCharArray();
而不是

static final String text1 = "some static text";

这样可以减少开销。它不需要在这些字符周围有一个完整的
字符串
实例。

一个小的历史漫游

在Java(1.0/1.1)的早期,使用字节数组而不是字符串对象实际上具有一些相当大的优势,如果您可以确定您永远不会需要ISO-8859-1之外的任何东西的话。在当时的虚拟机中,使用drawBytes()比使用drawString()快10倍多,而且它确实节省了当时仍然非常稀缺的内存,小程序过去的硬编码内存屏障是32 MB,后来是64 MB。不仅字节[]比字符串对象的嵌入字符[]小,而且还可以保存相对较重的字符串对象本身,如果有很多短字符串,这会产生很大的不同。此外,访问纯字节数组也比使用字符串的访问器方法及其所有额外的边界检查要快


但是,由于Java1.2中drawBytes的速度不再快了,而且当前的JIT比当时的Symantec JIT好得多,因此byte[]数组相对于字符串剩下的最小性能优势就不再值得这么麻烦了。内存优势仍然存在,因此在一些非常罕见的极端情况下,它可能仍然是一个选项,但现在,如果它不是真的必要的话,就不应该考虑它。

这甚至假设将它存储为字节,并在每次访问它时创建一个新字符串,这首先是一个好主意。@mmyers:我正要开始那:)有可能他使用了字符集选项,我不记得了——尽管如此,这似乎是一个不受欢迎的想法。很高兴我问了。除非你存储了数千兆或千兆的字符串,否则我甚至不会考虑这样做。使用的情况是在swing客户端缓存中。被告知在JTable中,这将节省内存。