String 是一个奇怪的引用类型
开局两张图,内容全靠刷!


马甲哥看到这样的现象,一开始还是有点懵逼。
这个例子,string是纯粹的引用类型,但是在函数传值时类似于值传递;
我之前给前后示例的内存变化图吧:

根因就是大多数高级语言都把String设计成不可变的:由一个字符串池管理字符串面值。
为什么被设计成不可变。
总结起来:
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打印结果为:Hello www.cnblogs.com

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点赞/转载),阅读/关注不是目的,更希望得到更多的阅读反馈、互相促进认知的提升(相当真诚️)。
String 是一个奇怪的引用类型的更多相关文章
- SpannableString的一个奇怪的问题
今天使用spannableString遇到一个奇怪的问题,就是在setspan的时候,原本可以写成 spannableString.setSpan(new RelativeSizeSpan(0.5f) ...
- String为值类型还是引用类型
关于String为值类型还是引用类型的讨论一直没有平息,最近一直在研究性能方面的问题,今天再次将此问题进行一次明确.希望能给大家带来点帮助. 如果有错误请指出. 来看下面例子: //值类型 int a ...
- 一个奇怪的JS函数
今天在分析一个jQuery插件源码的时候,发现了一个奇怪的函数. 这个函数的目的是为数字补零,如传入7,输出07,传入12输出12.由于是对时间补零,只截取后两位. // add leading ze ...
- string 是值类型,还是引用类型(.net)[转]
转自http://hi.baidu.com/newfzks/item/b805f0f4edb0810dd89e7290 string 是值类型,还是引用类型(.net) 一. string 类型的用法 ...
- 转:C# String为值类型还是引用类型
关于String为值类型还是引用类型的讨论一直没有平息,最近一直在研究性能方面的问题,今天再次将此问题进行一次明确.希望能给大家带来点帮助,如果有错误请指出. 来看下面例子: //值类型 int a ...
- ERROR: “System.Web.Mvc.Controller.File(string, string, string)”是一个“方法”
ERROR: “System.Web.Mvc.Controller.File(string, string, string)”是一个“方法”,这在给定的上下文中无效 这是一个与Controller.F ...
- MinGW 和 MSVC 下,使用 FILE 类型的一个奇怪的问题
今天遇到一个奇怪的问题. 开发环境: 1. Eclipse CDT,使用 MinGW 的 gcc 编译器和函数库 2. Visual Studio 2008 问题描述: 在 eclipse cdt 中 ...
- 遇到delphi连接sql一个奇怪的问题:未指定的错误,加大了命令的等待时间为600即可了
遇到delphi连接sql一个奇怪的问题:未指定的错误,加大了命令的等待时间为600即可了 找了一下午没解决.
- 【Windows 7】发现一个奇怪的现象
最近在Windows7-32位操作系统上发现一个奇怪的现象,不知道64位操作系统上会不会发生这个现象.这个现象就是:如果系统上的一个或多个账户没有设置密码,那么在此条件下终止winlogon.exe进 ...
随机推荐
- 后端Spring Boot+前端Android交互+MySQL增删查改(Java+Kotlin实现)
1 前言&概述 这篇文章是基于这篇文章的更新,主要是更新了一些技术栈以及开发工具的版本,还有修复了一些Bug. 本文是SpringBoot+Android+MySQL的增删查改的简单实现,用到 ...
- Linux(CentOS7)安装与卸载MySQL8.0图文详解
Mysql数据库的安装对于开发者来说,是我们必然会面对的问题,它的安装过程其实并不复杂,并且网络上的安装教程也非常多,但是对于新手来说,各种不同形式的安装教程,又给新手们带来了要选择哪种方式进行安装的 ...
- JPA之排序条件查询
List<Monitoring> monitoringList = repository.findAll((root, query, cb) -> { List<Predica ...
- Sublime text3 的安装【解决官网被墙问题】
使用提示 主要是https://packagecontrol.io 这个被墙了 下载不下来导致的错误,把下载链接改为国内的:修改sublime text3的package setting 的user配 ...
- hdu4499 搜索
题意: 给你一个棋盘,最大是5*5的,问你最多可以放多少个炮,炮和炮之间不可以相互攻击,这块只的是只能走一步,不存在两个炮中间三个棋子的情况.. 思路: 刚开始想的是把所有的空位置都 ...
- hdu1526 二分匹配+ floyd
题意: 有N个插座,M个用电器,和K种转换器(每种有无限个),问最少多少个用电器无法充电. 思路 : 总的电器数 减去 电器和插座的最大匹配数 我有的是map去映射每一个串,根据转换器建边,然后跑一 ...
- Linux配置yum源(本地源和网络源)
目录 一:配置本地yum源 二:配置网络yum源 更新源可以获取最新的软件信息,以更新您的系统 Redhat7配置源 YUM(Yellow dog Updater Modified): yum是Re ...
- Winrar漏洞复现(CVE-2018-20250)
本文讲的是Winrar漏洞利用脚本的使用方法,至于Winrar漏洞的原理,请移步--> Winrar目录穿越漏洞复现 本次利用脚本出处--> https://github.com/back ...
- Flask 实现分页
pager.html <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...
- Win10 ntoskrnl.exe蓝屏解决
主机一直用的是无线网卡,装Win10下载驱动.不管是Window10自己更新,还是通过驱动人生.驱动精灵等安装的Killer网卡驱动,均日常导致蓝屏. 状态是这样的:玩游戏蓝屏.检测系统蓝屏.清垃圾蓝 ...