String是一个奇怪的引用类型

news/2024/7/19 16:33:46 标签: 字符串, 编程语言, js, web, html
htmledit_views">
html" title=js>js_content">

点击蓝字

关注我们

开局两张图,内容全靠刷。

马甲哥看到这样的现象,一开始还是有点懵逼。

这个例子,string是纯粹的引用类型,但是在函数传值时类似于值传递;我之前给前后示例的内存变化图吧:

根因就是大多数高级语言都把String设计成不可变的: 由一个html" title=字符串>字符串池管理html" title=字符串>字符串面值。

为什么被设计成不可变。

这个我还真的搜索了一下[1]

总结起来:

  1. string 被设计为不可变, 是因为 string在现代任何语言中,使用很频繁:多个对象可能都是这个字符面值, 然后就设计一个Pool来存储string。
    既然pool里面共享字符面值,修改的时候又不能影响到别人,那就只好重新拷贝产生新的字符面值。

  2. 不可变资源消除了多线程中的资源竞争:对于文本的修改都会导致创建新空间,因此在多个线程同时访问文本无需设置锁,这对高频使用的String很友好。

  3. html" title=字符串>字符串不变性对于[在哈希表中使用html" title=字符串>字符串作为键]很友好,需要计算哈希值的对象必须是不可变的,以确保哈希值不变。

  • 一个有意思的现象是:String虽然是引用类型,html" title=字符串>字符串对比时却表现的像值类型

string str1="FooFoo";
string strFoo="Foo";
string str2= strFoo + strFoo;
return str1 == str2;           //  返回true

正因为String不可变性 & Pool的机制,频繁变更html" title=字符串>字符串,会在池中产生很多临时的不用的html" title=字符串>字符串,所以我们有了优化的套路:

StringBuilder

代表可变的html" title=字符串>字符串,一旦修改不会尝试创建新对象,而是动态扩展内存

var ss = new StringBuilder("Hello ", 100);  // 初次字符容量100
ss.Append("www.cnblogs.com");
Console.WriteLine(ss.ToString());  // ss打印结果为:222

Span

Span该出圈了,
Span提供对内存连续区域的类型安全访问,该内存可以位于堆、堆栈、甚至是非托管内存;
与String不可变性相关的是ReadOnlySpan(值类型), 提供内存数据的只读视图,每次切片不会产生新对象,而是在已存在的连续空间上创造新的视图。

var text = "https://www.cnblogs.com/JulianHuang/p/14817621.html";
ReadOnlySpan<char> nameSpan = text.AsSpan(8, 15);
nameSpan = nameSpan.Slice(4,7);
Console.WriteLine(nameSpan.ToString());

总结输出

今天从两张诡异的编程图聊到了String的不可变性、内存分布, 延伸谈到了

  1. String不可变性的设计设计考量(有先射箭再画靶的嫌疑☺️)

  2. 针对频繁修改的String如何做内存优化

不是自吹,文章内容在业界相当硬核(多次被各大佬/CSDN点赞/转载),阅读和关注不是目的,更希望得到更多的阅读反馈,互相促进认知的提升(相当真诚☺️)。

参考资料

[1]

这个我还真的搜索了一下: https://www.c-sharpcorner.com/UploadFile/230635/why-string-are-immutable-in-dotnet/

# 更多精彩

今天因为你的点赞,让我元气满满!


http://www.niftyadmin.cn/n/1864502.html

相关文章

非常适合新手的redis cluster搭建过程

Redis集群演进过程Redis单节点主从复制&#xff1a;复制主要实现了数据的多机备份&#xff0c;以及对于读操作的负载均衡和简单的故障恢复。故障恢复无法自动化&#xff1b;写操作无法负载均衡&#xff1b;存储能力受到单机的限制。哨兵&#xff08;Sentinel&#xff09;&#…

简单建立DLL和使用DLL

首先&#xff0c;这个只是最简单的一个说明而已&#xff0c;拿VS来说&#xff0c;有些特许的DLL就不是下面的方法生成和使用的&#xff0c;比如COM。 一.DLL中导出类&#xff0c;对象&#xff0c;方法 1. 创建一个空的Win32 Dynamic-Link Library项目Tes 2. 在项目中添加一个Te…

你怕是对MD5算法有误解

大家常听到“MD5加密”、“对称加密”、“非对称加密”&#xff0c;那么MD5属于哪种加密算法&#xff1f;面试官问这样的问题&#xff0c;准是在给你挖坑。"MD5加密"纯属口嗨&#xff0c;MD5不是加密算法&#xff0c;是摘要算法。今天小码甲带大家梳理加密算法、摘要…

Redis分布式锁抽丝剥茧

之前码甲哥写了两篇有关线程安全的文章&#xff1a;•你管这叫线程安全&#xff1f;•.NET八股文&#xff1a;线程同步技术解读分布式锁是"线程同步"的延续最近首度应用"分布式锁"&#xff0c;现在想想&#xff0c;分布式锁不是孤立的技能点&#xff0c;这…

.net 基础知识 ——条件语句

If 语句C#VBint i 3; if (i < 5) { Console.WriteLine("i 小于 5"); }Dim i As Integer 3 If i < 5 Then Console.WriteLine("i 小于 5") End Ifint i 9; if (!(i < 5)) { Console.WriteLine("i 大于等于 5"); }Dim i A…

使用 StateServer 保存 Session

StateServer 模式的实质是&#xff0c;把Session 存放在一个单独的进程里&#xff0c;此进程独立于 aspnet_wp.exe 或 w3wp.exe 。启用此服务后&#xff0c;在“任务管理器”中可以看到一个名为 aspnet_state.exe 的进程&#xff0c;下面开始说明一下设置的具体步骤&#xff1a…

ado.net连sql2005的问题

connection close掉之后&#xff0c;在sql2005里并不消失而是处于睡眠状态。 用loadrunner跑压力测试&#xff0c;发觉5个人&#xff0c;10个人&#xff0c;都正常&#xff0c;但20个人就不正常了。而且一到20个人之后连sql2005都连不进去了。在性能里监视sql2005的连接数和cpu…

未能创建Visual c# 2008编译器

一上班就遇到这个错误&#xff0c;害我忙活了大半天 这里记了两条命令&#xff0c;可以修复 devenv /resetsettings devenv /resetskippkgs 如果修复不了&#xff0c;卸载重装在修复&#xff0c;我是这样修复好的&#xff0c;重装的时候最好完全卸载转载于:https://www.cnblogs…