原创地址:http://my.oschina.net/u/2323537/blog/530423java
之前学java基础的时候考虑过string占多少字节,百度后有人说一个汉字占两个字节,因此一个string的字节数是可变的,遇到一个汉字+2,遇到一个字母+1。笔者对此结论严重怀疑,一个string在分配内存空间的过程当中怎么可能会动态变化呢。笔者开始尝试测试string所占的字节数。数组
一:首先想到的是经过string的getBytes方法测试其所占长度,是否与上述结论一致。jvm
请看下面代码:测试
String a="中国"; System.out.println(a.getBytes().length);
返回结果为6。.net
这个结果与上述结论明显有出入,一个汉字占3个字节吗?显然不是这样的,由于一个char占两个字节,char是能够存放一个汉字的。getBytes方法只是将字符串转换为字节码,其转换关系在源码中能够找到,他是使用默认字符集将string转换为byte序列的,至于为啥每一个汉字在getBytes的时候是3个,还请大神指教。指针
二:经过outofmemory异常测试
调试
首先咱们的电脑内存空间是有限的,因此若是定义一个数组的长度过长,必定会抛出outofmemory异常,每一个人的整块内存空间应该是不同的,因此笔者先测了下本身电脑上的最大整块内存空间,经屡次调试,发现内存空间大小为1365966832字节。code
byte b[]=new byte[1365966832];
这是一个临界值,再加1就会抛出outofmemory异常。大概1.3个G。对象
同理测试,用string数组建立的话,临界值为341491708。blog
上面的数除如下面的数等于4!故为4个字节。
三:因为建立对象的初期,jvm虚拟机会把分配到的内存空间所有初始化为0(不包括对象头),其值为这些字段的数据类型对应的0值(引自深刻理解java虚拟机),因此目前数组中的每一个string仍是null值(string对应的0值为null),那么根据最开始的可变理论,咱们上述的结论还不够有说服力。咱们开始为该数组赋值。
String str[]=new String[341491708]; for(int i=0;i<str.length;i++){ str[i]="f"; } System.out.println(str[0]);
结果没有抛出异常,数组长度再大也能够。说明字节长度不变就是4个字节。
四.有人可能会说,这样声明的字符串是被放到常量池里了,返回的只是个引用。ok咱们利用最后零散的的内存空间new字符串出来。
--------
擦擦擦,刚刚死机了,感谢oschina的自动保存功能。。。
--------
String str[]=new String[341491708]; for(int i=0;i<str.length;i++){ str[i]=new String("f"); if(i>996710){ System.out.println(i); } }
结果个人电脑不到100万就溢出了,换再长的字符串也同样。这里想亲手作实验的童鞋注意,之因此有个if判断才打印是由于打印很耗时,过滤掉前面没用的打印而已。
综上所述string占4字节
----------------------------------------------------割割割割割割----------------------------------------
以上论断是错的,具体缘由应该与c语言的指针类型有关,如今笔者还有些东西没有想清楚,想清楚后会改,敬请期待~