none
字符串占多少个byte RRS feed

  • 问题

  • 比如:String a="a";

    a字符串变量里的a占用多少个byte

    有些新建对象需要用到字节来初始化,究竟要输入多大的数字呢?比如

                StringBuilder temp = new StringBuilder(255);
    究竟stringbuilder  temp的大小是多少?


    2011年8月4日 7:52

答案

  • String a = "a";

    “a” 是一个字符串,其长度为 1,占用 2 个字节,因为 String 在 .NET 中为 UTF-16 编码。一个字符占用 2 个字节存储。

    对于本身变量 a 来说,它在 Execution Thread 上会有一个引用的本地变量,引用本身是一个对象指针,对于变量 a,其引用的大小为 4 个字节或者 8 个字节,根据操作系统的默认 HANDLE 结构的大小而不同。

    进一步,变量 a 指向的托管堆对象,也就是字符 "a",是一个 System.String 的实例对象,它的内容 "a" 占用 2 字节,但其对象本身还需要一个 2 个字节的长度标识符,4 个字节的 Type Object Ptr 和 1 个字节的 Sync Block Index,注意,更正一下上楼 MVP 的说法,托管的字符串不是 null-terminated 的,也就是末尾没有 \0,而是靠我刚才提到的长度标识符来计算其长度的。

    所以,现在应该十分明了了。领情注意,sizeof 或者 GetByteCount 出来的,只不过是其内容的长度,而不是本身对象在内存中到底有多长。


    Mark Zhou

    但其对象本身还需要一个 2 个字节的长度标识符,4 个字节的 Type Object Ptr 和 1 个字节的 Sync Block Index你这句话即是说要7个字节?
    2011年8月8日 16:39

全部回复

  • 您好

    請參考以下方式,透過 System.Text.Encoding.Default.GetByteCount

       String a = "a";
    
    
    
       int byteCount = System.Text.Encoding.Default.GetByteCount(a);
    
    

     


    歡迎參觀我的Blog.NET菜鳥自救會

    • 已建议为答案 ubosm 2011年8月4日 10:06
    2011年8月4日 8:55
  • 从.net机制看,你这个写法是初始化时赋值的,所以,这个"a"是启动时分配的内存,执行到这里时,只是用一个引用只想字符串池中的常量字符串而已。变量a本身是一个地址的长度,指向的字符串应该是2个字符,a和末尾识别符\0。GetBytesCount返回结果是1,表示有效字符转换为字节对应的长度。

    StringBuilder temp = new StringBuilder(255);

    这个长度可以认为接近255,但肯定大于510。类对象的创建,需要在objectHash中添加对象和引用,以及其他垃圾回收机制内容,导致不是510,但多不了多少。你可以认为是510。因为.net默认使用的是UNICODE。


    2011 c# mvp China. *George读起来像不像“饺子”?我爱吃饺子,我叫George。
    2011年8月5日 6:27
    版主
  • By the way,

      不同的编码将会获得不同的字节数。

    2011年8月8日 7:08
    版主
  • String a = "a";

    “a” 是一个字符串,其长度为 1,占用 2 个字节,因为 String 在 .NET 中为 UTF-16 编码。一个字符占用 2 个字节存储。

    对于本身变量 a 来说,它在 Execution Thread 上会有一个引用的本地变量,引用本身是一个对象指针,对于变量 a,其引用的大小为 4 个字节或者 8 个字节,根据操作系统的默认 HANDLE 结构的大小而不同。

    进一步,变量 a 指向的托管堆对象,也就是字符 "a",是一个 System.String 的实例对象,它的内容 "a" 占用 2 字节,但其对象本身还需要一个 2 个字节的长度标识符,4 个字节的 Type Object Ptr 和 1 个字节的 Sync Block Index,注意,更正一下上楼 MVP 的说法,托管的字符串不是 null-terminated 的,也就是末尾没有 \0,而是靠我刚才提到的长度标识符来计算其长度的。

    所以,现在应该十分明了了。领情注意,sizeof 或者 GetByteCount 出来的,只不过是其内容的长度,而不是本身对象在内存中到底有多长。


    Mark Zhou
    2011年8月8日 13:55
  • String a = "a";

    “a” 是一个字符串,其长度为 1,占用 2 个字节,因为 String 在 .NET 中为 UTF-16 编码。一个字符占用 2 个字节存储。

    对于本身变量 a 来说,它在 Execution Thread 上会有一个引用的本地变量,引用本身是一个对象指针,对于变量 a,其引用的大小为 4 个字节或者 8 个字节,根据操作系统的默认 HANDLE 结构的大小而不同。

    进一步,变量 a 指向的托管堆对象,也就是字符 "a",是一个 System.String 的实例对象,它的内容 "a" 占用 2 字节,但其对象本身还需要一个 2 个字节的长度标识符,4 个字节的 Type Object Ptr 和 1 个字节的 Sync Block Index,注意,更正一下上楼 MVP 的说法,托管的字符串不是 null-terminated 的,也就是末尾没有 \0,而是靠我刚才提到的长度标识符来计算其长度的。

    所以,现在应该十分明了了。领情注意,sizeof 或者 GetByteCount 出来的,只不过是其内容的长度,而不是本身对象在内存中到底有多长。


    Mark Zhou

    但其对象本身还需要一个 2 个字节的长度标识符,4 个字节的 Type Object Ptr 和 1 个字节的 Sync Block Index你这句话即是说要7个字节?
    2011年8月8日 16:39
  • 至少是这样,但是这些字节可能是不连续的,因为 String 的特殊性,它的内容 (char[]) 可能会被 Pin 到内存的某个区域。更多信息请参考 GCHandle。
    Mark Zhou
    2011年8月10日 9:19
  • 好的

    2011年8月10日 10:12