String是一个奇怪的引用类型
点击蓝字
关注我们
开局两张图,内容全靠刷。
马甲哥看到这样的现象,一开始还是有点懵逼。
这个例子,string是纯粹的引用类型,但是在函数传值时类似于值传递;我之前给前后示例的内存变化图吧:
根因就是大多数高级语言都把String设计成不可变的: 由一个字符串池管理字符串面值。
为什么被设计成不可变。
这个我还真的搜索了一下[1]:
总结起来:
string 被设计为不可变, 是因为 string在现代任何语言中,使用很频繁:多个对象可能都是这个字符面值, 然后就设计一个Pool来存储string。
既然pool里面共享字符面值,修改的时候又不能影响到别人,那就只好重新拷贝产生新的字符面值。不可变资源消除了多线程中的资源竞争:对于文本的修改都会导致创建新空间,因此在多个线程同时访问文本无需设置锁,这对高频使用的String很友好。
字符串不变性对于[在哈希表中使用字符串作为键]很友好,需要计算哈希值的对象必须是不可变的,以确保哈希值不变。
一个有意思的现象是:String虽然是引用类型,字符串对比时却表现的像值类型
string str1="FooFoo";
string strFoo="Foo";
string str2= strFoo + strFoo;
return str1 == str2; // 返回true
正因为String不可变性 & Pool的机制,频繁变更字符串,会在池中产生很多临时的不用的字符串,所以我们有了优化的套路:
StringBuilder
代表可变的字符串,一旦修改不会尝试创建新对象,而是动态扩展内存
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的不可变性、内存分布, 延伸谈到了
String不可变性的设计设计考量(有先射箭再画靶的嫌疑☺️)
针对频繁修改的String如何做内存优化
不是自吹,文章内容在业界相当硬核(多次被各大佬/CSDN点赞/转载),阅读和关注不是目的,更希望得到更多的阅读反馈,互相促进认知的提升(相当真诚☺️)。
参考资料
[1]
这个我还真的搜索了一下: https://www.c-sharpcorner.com/UploadFile/230635/why-string-are-immutable-in-dotnet/
# 更多精彩
面试八股文:你写过自定义任务调度器吗?
你管这叫"线程安全"?
墙裂推荐:这可能是CAP理论的最好解释
全网最通透的“闭包”认知 · 跨越语言
鹅厂二面,Nginx回忆录
实话实说:只会.NET,会让我们一直处于鄙视链、食物链的下游
什么是云原生?
今天因为你的点赞,让我元气满满!
String是一个奇怪的引用类型相关推荐
- java线程未执行完成,java线程测试-一个奇怪的景况-执行未完成直接结束了
java线程测试-一个奇怪的状况-执行未完成直接结束了 import org.junit.Test; /** * 同步线程测试 * @author jview * */ public class te ...
- string 是值类型,还是引用类型(.net)
一. string 类型的用法比较像值类型 稍微有点.NET 编程知识的人都知道 string是引用类型.我为什么还有此一问?因为string的使用非常像值类型.举个例子: string str = ...
- 古堡算式 福尔摩斯到某古堡探险,看到门上写着一个奇怪的算式: ABCDE * ? = EDCBA
/** 古堡算式福尔摩斯到某古堡探险,看到门上写着一个奇怪的算式:ABCDE * ? = EDCBA他对华生说:"ABCDE应该代表不同的数字,问号也代表某个数字!"华生:&quo ...
- 古堡算式(福尔摩斯到某古堡探险,看到门上写着一个奇怪的算式:ABCDE * ? = EDCBA)
/*** * 福尔摩斯到某古堡探险,看到门上写着一个奇怪的算式:ABCDE * ? = EDCBA他对华生说:"ABCDE应该代表不同的数字,问号也代表某个数字!"华生:" ...
- 古堡算式 福尔摩斯到某古堡探险,看到门上写着一个奇怪的算式: ABCDE * ? = EDCBA
古堡算式 福尔摩斯到某古堡探险,看到门上写着一个奇怪的算式: ABCDE * ? = EDCBA (abcde不能重复!) #include <stdio.h> #include < ...
- java包装和引用_回顾值传递和引用传递关于Java是值传递还是引用传递,网上有不一样的说法。1、基本类型或基本类型的包装类以及String是值传递,引用类型是引用传递。2...
回顾值传递和引用传递 关于Java是值传递还是引用传递,网上有不一样的说法. 1.基本类型或基本类型的包装类以及String是值传递,引用类型是引用传递. 2.Java中只有值传递. 关于这个问题应该 ...
- 一个奇怪的问题:匿名内部类用Lambda替换以后出现了cannot be cast to class的问题
文章目录 遇到问题 学习过程中的问题总结 遇到问题 最近在学习<Spring实战>,学习到第六章的Spring Data端点添加自定义的超链接时遇到了一个奇怪的问题. 当我向http:// ...
- MinGW 和 MSVC 下,使用 FILE 类型的一个奇怪的问题
今天遇到一个奇怪的问题. 开发环境: 1. Eclipse CDT,使用 MinGW 的 gcc 编译器和函数库 2. Visual Studio 2008 问题描述: 在 eclipse cdt 中 ...
- Delphi XE 使用 MySQL 数据库一个奇怪的问题
Delphi XE 使用 MySQL 数据库一个奇怪的问题 我用的是自带的 ADO 组件连接 MYSQL ,连接很简单,如下: 1.下载一个 MYSQL 驱动安装上 下载地址 2.连接串 Adoc.C ...
最新文章
- 基于javaGUI的文档识别工具制作
- 数据统计之日分类商品访问量
- win 下squid的配置
- office 2007打字慢问题
- java 反射加实例化内部类
- Tkinter中常用的函数
- WEB技术架构的资源链接。
- 《Java开发手册》解读:大整数传输为何禁用Long类型?
- Sentinel(一)之简介
- java deque.pop_Java ArrayDeque pop()方法
- 大数据可视化有哪些优势
- 三菱PLC编程软件 GX Developer 8.86 中文版的下载与安装 (win 7 64位)
- zai php 里面写js,php中写入js代码
- outlook2016登录163邮箱教程
- 爬虫 -----beautifulsoup、Xpath、re (三)附淘宝比价定向爬虫
- 机器学习入门系列之PCA降维
- uoj 198: [CTSC2016]时空旅行
- send_nsca passive monitor setup notes
- ppt文件提示处于受保护状处理方案
- .NET的前景如何?你的问题答案都在这里-2017
热门文章
- 彻底删除 XP 自带的 Windows Messenger方法
- testng接口自动化测试_Java+Maven+TestNG接口(API)自动化测试教程(10) 使用 Jenkins 构建自动化测试持续集成...
- 网络虚拟化有几种实现方式_停车场管理系统的防砸车功能有几种方式?如何实现?...
- Docker:Nginx-Redis-Mysql-PHP 部署
- CentOS 6.5 部署WordPress
- 每个人都要在自己的“时区”里找到自己的快乐
- MFC 单选按钮Radio使用注意
- jQuery.ajax实现根据不同的Content-Type做出不同的响应
- 最新版富文本编辑器UEditor操作教程
- PPT设计中的用图问题