我试图找出有效的数据类型。 我知道int是4个字节,char是一个字节。
我是对的吗? 你认为哪一个更好?
答案 0 :(得分:9)
客观答案首先:
不那么客观的答案:选择能够为您的应用程序提供最佳设计的数据结构。
如果您的应用程序中有特定的约束,请发布有关您需要处理的数据和您所拥有的约束的更多详细信息。
答案 1 :(得分:7)
String
不仅仅是一个字符数组,它是一个独立的对象,并且具有除其后备char[]
以外的字段。例如,String
有三个int
字段:offset
,count
和hash
。因此,空字符串通常是16个字节(因为我们还需要考虑char[]
字段)加上正常的8个字节的对象开销。另请注意,char[]
本身是一个对象,并且具有int
字段length
和相关的对象开销。一旦考虑了所有这些,然后就可以为每个字符添加两个(不是一个!)字节。
所以,对于一个10个字符的字符串:
int
字段: 12 字节char[]
字段: 8 字节
int
字段: 4 字节这大约是60个字节。我说“约”,因为其中一些依赖于VM。
答案 2 :(得分:1)
您对Java中的char
不正确:因为它们旨在容纳16位UNICODE代码点they take two, not one byte each。最后,两个表示将占用相同的内存量。
您应该选择对您最有意义的数据类型,类的设计者以及代码的读者。除非您需要的对象数量可能会溢出可用内存,否则内存问题不应该是您设计优先级的首要问题。即便如此,在优化之前,您应该仔细进行内存分析。
答案 3 :(得分:0)
字符大小为2个字节。它们相当于无符号短整数,因此字符的值可以在[0,65535]之间。
String占用的字节数实际为:
string.length * 2
因此,对于您的示例,10个字符的字符串占用20个字节,而不是10个字节。
这将是只是字符串内容。 String
类中还有其他变量,当然会占用更多的字节。甚至一个空对象占用一定数量的字节,这些字节将根据JVM实现而变化。
但是,只是字符内容每个字符占用2个字节。
但不要担心这是最确定的过早优化。清洁代码比闪电快速代码通常更重要。选择适当的数据类型,编写易于遵循和阅读的代码。这些事情更重要。
如果您担心在内存中持有大字符串,请考虑更改您的方法。我看到大字符串最常见的问题是当新程序员将整个文件读入内存时。
如果您这样做,请尝试逐行处理数据。只能一次保存内存中所需的最小单位,执行处理,然后继续。
答案 4 :(得分:0)
我知道int是4个字节
正确
和char是一个字节。
char
是一个16位无符号整数,所以2个字节
包含五个整数(4 * 5 = 20个字节)的对象
Object
的标头在32位JVM上为12字节,在64位JVM上为16字节。对象是8字节对齐的,如果更改,可能会对齐16或32字节。
这意味着new int[5]
使用16 + 20 + 4(填充)= 40字节
一个有十个字符的String对象。 (假设它有10个字符10 * 1 = 10个字节)
一个字符串使用带有标题和长度字段等的~24个字节,但它包含一个包含实际字符的char [],这是另外的16 + 20 + 4 = 40个字节。
检查此方法的一种简单方法是使用以下方法。确保使用-XX:-UseTLAB
来改善内存记帐(但对于多线程编程来说速度较慢)
public static void main(String... ignored) {
char[] chars = new char[10];
long used = memoryUsed();
String s= new String(chars);
long diff = memoryUsed() - used;
if (diff == 0) throw new AssertionError("You must set -XX:-UseTLAB on the command line");
System.out.printf("Creating a String of 10 characters used %,d bytes of memory%n", diff);
}
private static long memoryUsed() {
return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
}
打印
Creating a String of 10 characters used 64 bytes of memory