C# string 防止GC及内存分配

这篇具有很好参考价值的文章主要介绍了C# string 防止GC及内存分配。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

前言:

字符串的内存分配

如何理解C#字符串常量池

如何防止string产生GC

C# 使用注意情况 


前言:

在 C# 中,字符串类型是一个引用类型,它的内存分配方式与其他引用类型类似,都是在堆上分配内存。

字符串的内存分配

字符串类型的内存分配方式有以下几种:

  1. 字符串常量池:字符串常量池是一块特殊的内存区域,用于存储字符串常量。当我们定义一个字符串常量时,它会被分配到字符串常量池中。如果我们定义多个相同的字符串常量,它们会共享同一个内存地址,从而节省内存空间。

  2. 字符串字面量:字符串字面量是一种特殊的字符串常量,它们是在编译时就确定的字符串常量。当我们使用字符串字面量时,它们会被分配到字符串常量池中。

  3. 字符串对象:字符串对象是通过 new 关键字创建的字符串实例。当我们创建一个字符串对象时,它会被分配到堆上的一个新的内存地址。

需要注意的是,由于字符串是不可变类型,所以在对字符串进行修改时,会创建一个新的字符串对象,从而增加内存分配的开销。为了避免这种情况,可以使用 StringBuilder 类来优化字符串操作,它可以在内部维护一个可变的字符串缓冲区,从而避免创建新的字符串对象。

下面是一个示例代码,演示了字符串的内存分配方式:

string str1 = "hello"; // 字符串常量池
string str2 = "hello"; // 字符串常量池,与 str1 共享同一个内存地址
string str3 = new string('qqqq', 100); // 堆上分配内存
string str4 = "hello" + "world"; // 字符串常量池,编译时就确定了
string str5 = str1 + str2; // 堆上分配内存
StringBuilder sb = new StringBuilder(); // 堆上分配内存
sb.Append("hello");
sb.Append("world");
string str6 = sb.ToString(); // 堆上分配内存,但是避免了创建多个字符串对象

 在上面的代码中,我们定义了多个字符串变量,演示了字符串的内存分配方式。需要注意的是,字符串常量池和堆上分配内存的方式都会受到垃圾回收器的影响,如果字符串对象没有被引用,它们会被垃圾回收器回收。

如何理解C#字符串常量池

C# 字符串常量池是一种特殊的内存区域,用于存储字符串常量。在 .NET Framework 中,字符串常量池是由运行时环境维护的,它的作用是尽可能地重用字符串常量,从而节省内存空间。

当我们定义一个字符串常量时,它会被分配到字符串常量池中。如果我们定义多个相同的字符串常量,它们会共享同一个内存地址,从而节省内存空间。例如:

string str1 = "hello";
string str2 = "hello";

在上面的代码中,str1 和 str2 都是字符串常量,它们的值相同,因此它们会共享同一个内存地址。这意味着,str1 和 str2 本质上是同一个字符串对象,它们的引用指向同一个内存地址。

需要注意的是,字符串常量池只适用于字符串常量,它不适用于字符串对象。例如:

string str3 = new string('a', 10);
string str4 = new string('a', 10);

在上面的代码中,str3 和 str4 都是字符串对象,它们的值相同,但是它们并不共享同一个内存地址,因为它们是通过 new 关键字创建的。这意味着,str3 和 str4 本质上是不同的字符串对象,它们的引用指向不同的内存地址。

需要注意的是,字符串常量池是有大小限制的,如果字符串常量池中已经存在了大量的字符串常量,新的字符串常量可能会被分配到堆上。此外,字符串常量池的大小也会受到垃圾回收器的影响,如果字符串常量没有被引用,它们会被垃圾回收器回收。

如何防止string产生GC

在 C# 中,字符串类型是一个引用类型,它的操作比较常见,因此在编写高性能的 C# 代码时,需要对字符串类型进行优化。下面是一些优化字符串类型的建议:

  1. 避免使用字符串拼接操作,因为字符串拼接操作会创建新的字符串对象,从而增加 GC 的负担。可以使用 StringBuilder 类来优化字符串拼接操作。

  2. 避免使用字符串的 + 运算符,因为它会创建新的字符串对象,从而增加 GC 的负担。可以使用 string.Concat 方法或 string.Join 方法来优化字符串拼接操作。

  3. 避免使用字符串的 Substring 方法,因为它会创建新的字符串对象,从而增加 GC 的负担。可以使用 string.AsSpan 方法来避免创建新的字符串对象。

  4. 避免使用字符串的 ToLower 或 ToUpper 方法,因为它们会创建新的字符串对象,从而增加 GC 的负担。可以使用 string.Create 方法和 string.Span 来避免创建新的字符串对象。

  5. 使用字符串常量或字符串字面量来代替字符串变量,因为字符串常量和字符串字面量会被分配到字符串常量池中,从而可以重用已有的字符串对象,减少内存分配的开销。

  6. 将字符串的长度缓存到一个变量中,避免在循环中多次计算字符串的长度,从而减少计算时间和 CPU 负担。

  7. 避免使用 string.Format() 方法,因为它会创建新的字符串对象,从而增加 GC 的负担。可以使用插值字符串或 StringBuilder 类来代替 string.Format() 方法。

  8. 避免在字符串操作中使用大量的临时字符串,因为它会增加 GC 的负担。可以使用 StringBuilder 类来优化字符串拼接操作。

下面是一个示例代码,演示了如何优化字符串类型:

string str1 = "hello";
string str2 = "world";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.Append(str1);
    sb.Append(str2);
}
string str3 = sb.ToString();
int length = str3.Length;
int index = str3.IndexOf(str1, StringComparison.OrdinalIgnoreCase);

在上面的代码中,我们使用了 StringBuilder 类来优化字符串拼接操作,使用了字符串的 Length 属性来代替 Count() 方法,使用了字符串的 IndexOf() 方法来代替 Contains() 方法。我们还避免使用了字符串的 ToUpper() 和 ToLower() 方法,使用了 StringComparison.OrdinalIgnoreCase 来代替大小写转换操作。 


C# string使用注意情况 

  1. 避免使用字符串的 GetHashCode() 方法,因为字符串的 GetHashCode() 方法计算哈希值时会考虑字符串的长度和内容,从而增加计算时间和 CPU 负担。可以使用 FNV-1a 算法或 MurmurHash 算法来代替字符串的 GetHashCode() 方法。

  2. 使用字符串的 IndexOf() 方法来代替 Contains() 方法,因为 IndexOf() 方法可以指定搜索的起始位置,从而减少搜索时间。

  3. 使用字符串的 Length 属性来代替 Count() 方法,因为 Length 属性是一个字段,而 Count() 方法是一个方法,它需要遍历整个字符串来计算长度。

  4. 尽量使用静态字符串方法,如 string.IsNullOrEmptystring.IsNullOrWhiteSpacestring.Compare 等,它们具有更好的性能和更低的内存分配开销。文章来源地址https://www.toymoban.com/news/detail-486864.html

到了这里,关于C# string 防止GC及内存分配的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C# 把字符串(String)格式转换为DateTime类型方法

    Convert.ToDateTime(string)  注意:string格式有要求,必须是yyyy-MM-dd hh:mm:ss 方式二:DateTime.Parse(string) 参考:将字符串转换为 DateTime | Microsoft Learn DateTime.Tostring()//这个转换之后是YYYY/MM/DD HH:MM:SS DateTime.ToShortString()//这个转换之后是YYYY/MM/DD Convert.ToDateTime(string)//string是你要转换成时间

    2024年02月09日
    浏览(52)
  • C#用string.Replace方法批量替换某一类字符串

    目录 一、关于字符串及其操作常识 二、String.Replace 方法 1.重载  2.Replace(Char, Char) 3.Replace(String, String)  (1)实例: (2)生成结果: 4.Replace(String, String, StringComparison) 5.Replace(String, String, Boolean, CultureInfo) (1)实例         在字符串操作中,可以使用字符串对象的 Split方法

    2024年02月02日
    浏览(50)
  • 《Git入门实践教程》前言+目录

    版本控制系统(VCS)在项目开发中异常重要,但和在校大学生的交流中知道,这个重要方向并未受到重视。具备这一技能,既是项目开发能力的体现,也可为各种面试加码。在学习体验后知道,Git多样化平台、多种操作方式、丰富的资源为业内人士提供了方便的同时,也造成

    2024年02月10日
    浏览(56)
  • FPGA学习实践之旅——前言及目录

    很早就有在博客中记录技术细节,分享一些自己体会的想法,拖着拖着也就到了现在。毕业至今已经半年有余,随着项目越来越深入,感觉可以慢慢进行总结工作了。趁着2024伊始,就先开个头吧,这篇博客暂时作为汇总篇,记录在这几个月以及之后从FPGA初学者到也算有一定

    2024年02月03日
    浏览(44)
  • C# &OpenCV 从零开发(0):前言

    由于我想换个机器视觉+运动控制的工作,我就开始了自学机器视觉方向的技术。但是Halcon毕竟是商业化的库,国内用盗版还是怕被告。所以期望使用OpenCV。 OpenCV目前已知的方法的有两个版本 Python:用起来挺简单的,就是Python的语言不适合管理,感觉以后必定会出现问题,不适

    2024年01月18日
    浏览(55)
  • unity-内存GC

    Unity内存,原生内存(Native Memory)和托管内存(Managed Memory 其中Native Memory大家接触的会比较少,而且可操控性也比较少,例如AssetBundle,Texture,Audio这些所占的内存,这一部分内存是由Unity自身来进行管理的。我们平时开发通常会接触到的是Managed Memory,也就是我们自己定义的

    2023年04月09日
    浏览(29)
  • JVM 内存和 GC 算法

    对象头(Header) 运行时元数据(Mark word):哈希值、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳 类型指针 :指向类元数据,确定对象所属类型。如果是数组还要记录数组的长度 实例数据(Instance Data):类中的各类型变量以及父类的相关类型数据。

    2024年02月05日
    浏览(34)
  • jstat命令查看jvm内存情况及GC内存变化

    jstat [Options] pid [interval] [count] 参数说明: Options,选项,一般使用 -gc、-gccapacity查看gc情况 pid,VM的进程号,即当前运行的java进程号 interval,间隔时间(按该时间频率自动刷新当前内存情况),单位毫秒 count,打印次数,如果缺省则打印无数次 查看当前jvm内存情况 jstat -gc 12675

    2024年02月01日
    浏览(56)
  • java JVM 内存GC查看

    jstat命令可以查看堆内存各部分的使用量,以及加载类的数量。命令的格式如下: jstat [-命令选项] [vmid] [间隔时间/毫秒] [查询次数] 1、命令格式 jstat命令命令格式: jstat [Options] vmid [interval] [count] 参数说明: Options,选项,我们一般使用 -gcutil 查看gc情况 vmid,VM的进程号,即

    2024年01月22日
    浏览(28)
  • JVM学习 GC垃圾回收机制 (堆内存结构、GC分类、四大垃圾回收算法)

    🤖 作者简介: 努力的clz ,一个努力编程的菜鸟 🐣🐤🐥   👀 文章专栏: 《JVM 学习笔记》 ,本专栏会专门记录博主在学习 JVM 中学习的知识点,以及遇到的问题。   🙉 文章详情: 本篇博客是学习 【狂神说Java】JVM快速入门篇 的学习笔记,关于 GC垃圾回收机制 (堆内存结

    2023年04月19日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包