Java 在内存方面,哪个是有效的:char[]还是String?

Java 在内存方面,哪个是有效的:char[]还是String?,java,android,arrays,string,Java,Android,Arrays,String,我正在开发一个Android应用程序。应用程序的主要要求是在内存方面应该是高效的。那么,我应该从哪一个开始呢 String batterylevel; batterylevel = Float.toString(batteryPct); 或 在Oracle的JDK中,字符串有四个实例级字段: 字符数组 积分偏移量 整数字符计数 整数散列值 这意味着每个字符串都会引入一个额外的对象引用(字符串本身),以及字符数组本身之外的三个整数。(偏移量和字符计数允许在通过String#substring

我正在开发一个Android应用程序。应用程序的主要要求是在内存方面应该是高效的。那么,我应该从哪一个开始呢

String batterylevel;
batterylevel = Float.toString(batteryPct);


在Oracle的JDK中,字符串有四个实例级字段:

  • 字符数组
  • 积分偏移量
  • 整数字符计数
  • 整数散列值
这意味着每个字符串都会引入一个额外的对象引用(字符串本身),以及字符数组本身之外的三个整数。(偏移量和字符计数允许在通过String#substring()方法生成的字符串实例之间共享字符数组,这是一些其他Java库实现者避免的设计选择。)除了额外的存储成本之外,还有一个更高级别的访问间接性,更不用说字符串保护其字符数组的边界检查了

字符串是不可变的。这意味着,一旦创建了字符串,如果另一个进程可以转储内存,那么在GC启动之前(除了反射之外),就无法清除数据,这意味着浪费内存

对于数组,您可以在处理完数据后显式地擦除数据:您可以用任何喜欢的内容覆盖数组


就我所能得出的结论而言,就您的案例而言,is char[]在内存方面更好。

String是java中的类,它包装了char数组,正如您在代码中看到的那样

private final char value[];
因此,每次创建字符串对象时,它都由char数组支持。 而且String类有三个不同的字段,因为它比char数组占用更多的内存


但若你们看到了它的用法,那个么字符串比字符数组好,因为它是不可变的。您不必对字符串执行任何内存管理。性能方面的字符数组[]对于很少的操作(如果您是在大数据上执行的话)更快。

CString除了字符数组(或宽字符)之外,还包含字符串大小、分配的缓冲区大小和引用计数器(另外用作锁标志)。包含字符数组的缓冲区可能比它包含的字符串大得多——它允许减少花费时间的分配调用的数量。此外,当CString设置为零大小时,它仍然包含两个wchar字符

当然,当您将CString的大小与相应的C样式数组的大小进行比较时,数组会更小。但是,如果您希望尽可能广泛地操作字符串,您最终将为字符串大小、缓冲区大小以及有时的refcounter和/或guard标志定义自己的变量。实际上,您需要存储字符串大小,以避免每次需要时调用strlen。如果允许缓冲区大于字符串长度,则需要单独存储缓冲区大小,并避免每次向字符串添加或从字符串中减去时调用reallocs。以此类推——你可以用一些小规模的增长换取速度、安全性和功能性的显著提高

因此,答案取决于您将如何处理字符串。假设您需要一个字符串来存储用于日志记录的类的名称——在这里,一个C样式的字符串(const和static)就可以了。如果您需要一个字符串来操纵MFC或ATL相关类并广泛使用它,请使用CString族类型。如果您需要在应用程序的“引擎”部分操作与接口隔离的字符串,并且可能转换为其他平台,请使用std::string或编写自己的字符串类型以满足您的特殊需要(这在编写“胶水”时非常有用)代码放置在接口和引擎之间,否则最好使用std::string)

比较C++与CHAR的字符串[]


您多长时间检查一次电池电量,每次检查约16个字节会产生明显的差异?有一个刷新按钮可刷新电池电量。所以,这完全取决于用户。不过,没有明显的区别。Android系统可能分配了更多的内存,只是为了在用户点击按钮时使其变成橙色。您对内存使用的关注程度如何?(当Android应用程序出现内存问题时,通常是由于加载了兆字节的图像)嗯,我只关心20个字符串。我认为每当创建String类的对象时,实例变量也会被分配。20个这样的例子会有很大的不同吗?3个额外的整型字段(32位)+1个引用(64位)每个字符串=12+8=20。20*20=额外的400字节。您将节省惊人的0.0004兆字节。我认为你在寻找一些根本不值得的东西。还要注意,toCharArray调用创建了原始字符串内部缓冲区的副本。这意味着,只要垃圾收集器不释放内存,您实际上就在使用更多内存(读取:内存加倍)。我建议您使用字符串方法。
private final char value[];