C#之CLR内存字符串常量池(string)
C#中的string是比特殊的类,说引用类型,但不存在堆里面,而且String str=new String("HelloWorld")这样的重装也说没有的。
我们先来看一个方法:
class Program { static void Main(string[] args) { String s = "HelloWorld"; Console.WriteLine(s); } }
然后我们用ildasm.exe工具把它生成IL语言来看一看它里面是怎么玩的:
.method private hidebysig static void Main(string[] args) cil managed { .entrypoint // Code size 15 (0xf) .maxstack 1 .locals init ([0] string s) IL_0000: nop IL_0001: ldstr "HelloWorld" IL_0006: stloc.0 IL_0007: ldloc.0 IL_0008: call void [mscorlib]System.Console::WriteLine(string) IL_000d: nop IL_000e: ret } // end of method Program::Main
我们在里面并没有看见newObj(所以我们认为不在堆里面)的指令,只有一个特殊ldstr(load string)指令,它用从元数据获取一个文本常量字符串(字符串常量池)构造一个String对象。这证明了CLR说用一种特殊的方式构造了字符串。
我们再举一个简单例子看看:
class Program { static void Main(string[] args) { String s = "HelloWorld"; s = "HelloC#"; s = "HelloJava"; String s1= "HelloC#"; Console.WriteLine(s); } }
对照这个例子我们来看看内存图是怎么走的:
首先CLR内部机制会在运行这个方法之前就会有"prologue"代码去开辟内存空间,s和s1就说这个时候创建的。
我们创建了一个s的字符串对象,赋值为HelloWorld,把s插入栈,然后内部机制去字符串常量池中找HelloWorld副本,发现没有找到就会创建一个,接着会去保存这个HelloWorld在字符串常量池中的地址(Line1)。然后我们为s对象在赋值为HelloC#,由于同一个对象,栈中不做操作,去字符串常量池中找,没找到则创建,然后修改s所存储的地址(line 2),HelloJava同样的操作。 再创建一个s1的string对象,把s1压入栈,为S1赋值HelloC#,这个时候会去字符常量池中找,找到了就存这个引用。
相关推荐
-
C#中常量和只读变量的区别小结
常量和只读变量有以下区别: 1.常量必须在声明时就被初始化,指定了值后就不能修改了.只读字段可以在声明时被初始化,也可以在构造函数中指定初始化的值,在构造以后值就不能修改. 2.常量是静态的,而只读字段可以是静态和动态的 3.Const可以用在字段和局部变量,readonly只可以修饰字段
-
浅谈C#中的常量、类型推断和作用域
一.常量常量是其值在使用过程中不会发生变化的变量.在声明和初始化变量时,在变量前面家关键字const,就可以把该变量指定为一个常量: const int a=100;//a的值将不可以改变 常量的特征: 1.常量必须在声明时初始化.指定了其值以后,就不能再修改了.2.常量的值必须能在编译时用于计算.因此不能从一个变量中提取的值来初始化常量.如果需要这么做,应该使用只读字段.3.常量总是静态的,但注意,不必在常量的声明中包含修饰符static.(实际上,不允许)在程序中使用常量至少有3个好处: 1
-
c#只读字段和常量的区别,以及静态构造函数的使用实例
复制代码 代码如下: using System;using System.Collections.Generic;using System.Linq;using System.Text; namespace ConsoleApplication1{ /// <summary> /// 作者:it小金 /// 功能:c#只读字段和常量的区别,以及静态构造函数的使用 /// </summary> class Program { stat
-
解析C#中的常量及如何在C#编程中定义常量
常量是在编译时已知并在程序的生存期内不发生更改的不可变值.常量使用 const 修饰符进行声明.只有 C# 内置类型(System.Object 除外)可以声明为 const. 用户定义的类型(包括类.结构和数组)不能为 const.请使用 readonly 修饰符创建在运行时初始化一次即不可再更改的类.结构或数组. C# 不支持 const 方法.属性或事件. 可以使用枚举类型为整数内置类型(例如 int.uint.long 等等)定义命名常量. 常量必须在声明时初始化.例如: class C
-
C# 定义常量 两种实现方法
在C#中定义常量的方式有两种,一种叫做静态常量(Compile-time constant),另一种叫做动态常量(Runtime constant).前者用"const"来定义,后者用"readonly"来定义. 对于静态常量(Compile-time constant),它的书写方式如下: public const int MAX_VALUE = 10; 为什么称它为静态常量呢,因为如上声明可以按照如下理解(注意:如下书写是错误的,会出编译错误,这里只是为了方便说
-
c# 常量和字段
它的值是在编译时确定的.编译器将常量保存到程序集的元数据中,所有只能是编译器认识的基元类型作为常量. 常量被看成类的一部分,是看出静态成员. 代码引用一个常量符号,会在定义常量的元数据中查找该符号,提取之,并嵌入代码,生成的IL中是值本身. 在c#中使用的是const关键字. 字段:已一种数据成员,可以容纳任何的数据类型,不仅仅想常量一样只能存储基元类型. CLR支持类型字段和实例字段 类型字段:用于容纳字段数据的动态内存是在类型对象中分配的, 而类对象是在类型加载到一个AppDomain中创建
-
C# 基础入门--常量
常量,顾名思义,就是"不会改变的量". 我们平时书写的数字(比如12.85).字符(比如'F').字符串(比如"谢谢"),它们都属于"字面常量". 有一些常量既重要又容易出错,比如圆周率π的值为3.1415926......,所以,我们常常会使用自定义常量.如: namespace Test { class Program { static void Main(string[] args) { const double PI = 3.141592
-
C#之CLR内存字符串常量池(string)
C#中的string是比特殊的类,说引用类型,但不存在堆里面,而且String str=new String("HelloWorld")这样的重装也说没有的. 我们先来看一个方法: class Program { static void Main(string[] args) { String s = "HelloWorld"; Console.WriteLine(s); } } 然后我们用ildasm.exe工具把它生成IL语言来看一看它里面是怎么玩的: .met
-
Java 常量池详解之字符串常量池实现代码
目录 1.字符串常量池(String Constant Pool) 1.1:字符串常量池在Java内存区域的哪个位置? 1.2:字符串常量池是什么? 1.3 字符串常量池生成的时机? 如何将String对象放入到常量池 String 对象代码案例解析 new string(“abc”)创建了几个对象 解析public native String intern() 方法 Integer 对象代码案例解析 为啥Integer i1 =10 跟Integer.valueOf(10) 是相等的? 为啥I
-
Java String 字符串常量池解析
作为最基础的引用数据类型,Java 设计者为 String 提供了字符串常量池以提高其性能,那么字符串常量池的具体原理是什么,我们带着以下三个问题,去理解字符串常量池: 字符串常量池的设计意图是什么? 字符串常量池在哪里? 如何操作字符串常量池? 字符串常量池的设计思想 字符串的分配,和其他的对象分配一样,耗费高昂的时间与空间代价,作为最基础的数据类型,大量频繁的创建字符串,极大程度地影响程序的性能 JVM为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些优化 为字符串开辟一个字符串
-
深入解析JVM之内存结构及字符串常量池(推荐)
前言 Java作为一种平台无关性的语言,其主要依靠于Java虚拟机--JVM,我们写好的代码会被编译成class文件,再由JVM进行加载.解析.执行,而JVM有统一的规范,所以我们不需要像C++那样需要程序员自己关注平台,大大方便了我们的开发.另外,能够运行在JVM上的并只有Java,只要能够编译生成合乎规范的class文件的语言都是可以跑在JVM上的.而作为一名Java开发,JVM是我们必须要学习了解的基础,也是通向高级及更高层次的必修课:但JVM的体系非常庞大,且术语非常多,所以初学者对此非
-
Java String类的理解及字符串常量池介绍
目录 一. String类简介 1. 介绍 2. 字符串构造 二. 字符串常量池(StringTable) 1. 思考? 2. 介绍和分析 3. intern方法 三. 面试题:String类中两种对象实例化的区别 四. 字符串的不可变性 一. String类简介 1. 介绍 字符串广泛应用 在 Java 编程中,在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串. Java的String类在lang包里,java.lang.String是java字符串类,包含
-
Java 中的字符串常量池详解
Java中的字符串常量池 Java中字符串对象创建有两种形式,一种为字面量形式,如String str = "droid";,另一种就是使用new这种标准的构造对象的方法,如String str = new String("droid");,这两种方式我们在代码编写时都经常使用,尤其是字面量的方式.然而这两种实现其实存在着一些性能和内存占用的差别.这一切都是源于JVM为了减少字符串对象的重复创建,其维护了一个特殊的内存,这段内存被成为字符串常量池或者字符串字面量池.
-
Java中的字符串常量池详细介绍
Java中字符串对象创建有两种形式,一种为字面量形式,如String str = "droid";,另一种就是使用new这种标准的构造对象的方法,如String str = new String("droid");,这两种方式我们在代码编写时都经常使用,尤其是字面量的方式.然而这两种实现其实存在着一些性能和内存占用的差别.这一切都是源于JVM为了减少字符串对象的重复创建,其维护了一个特殊的内存,这段内存被成为字符串常量池或者字符串字面量池. 工作原理 当代码中出现字
-
Java字符串常量池示例详解
为什么会有常量池的概念? 不知道小伙伴们是否有思考过这个问题? 没有思考也无所谓,小编在这里类比一下,大家就会清晰了.什么是池? 我们听的最多的池,应该是数据库连接池. 为什么会有数据库连接池,其实就是为了节省资源,提高性能,防止重复创建连接,避免占用内存和网络资源. 常量池其实就是跟数据库连接池的目的都是一样的.那么他是如何实现的呢? 因为常量池是JVM的概念,源码我们也不好看,所以我们还以连接池来类比. 池化的目标就是缓存和管理 稍微提一点池化的概念,其实就是对资源做一个包装,在包装层来加一
-
java String类常量池分析及"equals"和"==”区别详细介绍
java "equals"和"=="异同 首先简单说一下"equal"和"==" ==操作对于基本数据类型比较的是两个变量的值是否相等, 对于引用型变量表示的是两个变量在堆中存储的地址是否相同, 即栈中的内容是否相同 equals操作表示的两个变量是否是对同一个对象的引用, 即堆中的内容是否相同. 综上,==比较的是2个对象的地址,而equals比较的是2个对象的内容. 再简单介绍一下String类 String类 又称作不可
-
java String源码和String常量池的全面解析
1. String 介绍,常用方法源码分析 2. String 常量池分析 常用方法 equals trim replace concat split startsWith 和 endsWith substring toUpperCase() 和 toLowerCase() compareTo String 介绍 String类被final所修饰,也就是说String对象是不可变量,并发程序最喜欢不可变量了.String类实现了Serializable, Comparable, CharSequ
随机推荐
- jquery 关键字“拖曳搜索”之“拖曳”以及 图片“提示自适应放大”效果 的实现
- 深入分析escape()、encodeURI()、encodeURIComponent()的区别及示例
- Node.js如何响应Ajax的POST请求并且保存为JSON文件详解
- 最新的黑客技术:XSS跨站脚本攻击详细介绍
- Oracle数字类型number自增的实现代码
- [Oracle] 常用工具集之SQL*Loader的用法
- javascript 文档的编码问题解决
- js实现微信分享代码
- Asp.Net 网站优化系列之数据库优化 分字诀 分表(纵向拆分,横向分区)
- 让table变成exls的示例代码
- Apache访问出现501 Method Not Implemented错误解决
- 通过ASP禁止指定IP和只允许指定IP访问网站的代码
- php中使用websocket详解
- Android通过滑动实现Activity跳转(手势识别器应用)
- Node.js中流(stream)的使用方法示例
- 根据公司需求写的一个linux 巡检小脚本
- javascript 遍历验证所有文本框的值
- c语言程序设计文件操作方法示例(CreateFile和fopen)
- js数组方法reduce经典用法代码分享
- vue将对象新增的属性添加到检测序列的方法