【C#】CLR内存那点事(string)

原文链接:http://www.cnblogs.com/guochenkai/p/3881227.html

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#,这个时候会去字符常量池中找,找到了就存这个引用。

 

转载于:https://www.cnblogs.com/guochenkai/p/3881227.html

展开阅读全文
博主设置当前文章不允许评论。

关于CreateEvent的那点

12-13

今天写了一个线程同步的程序,突然发现了一个很怪异的问题,不知道大家有没有遇到过,先把代码贴出来:rnrn[code=C/C++]# include rn# include rnrnint g_Count = 0;rnHANDLE g_hEvent;rnrnDWORD WINAPI Thread1(LPVOID lpParameter)rnrn while(TRUE)rn rn WaitForSingleObject(g_hEvent, INFINITE);rn g_Count++;rn if(g_Count == 10)rn break;rn printf("Thread1 %d\n", g_Count);rn SetEvent(g_hEvent); //重置事件对象为“触发态”rn rn return 0;rnrnrnDWORD WINAPI Thread2(LPVOID lpParameter)rnrn while(TRUE)rn rn WaitForSingleObject(g_hEvent, INFINITE);rn g_Count++;rn if(g_Count == 10)rn break;rn printf("Thread2 %d\n", g_Count);rn SetEvent(g_hEvent); //重置事件对象为“触发态”rn rn return 0;rnrnrnrnint main()rnrn HANDLE hThread1, hThread2;rnrn hThread1 = CreateThread(NULL, 0, Thread1, NULL, 0, NULL);rn hThread2 = CreateThread(NULL, 0, Thread2, NULL, 0, NULL);rn CloseHandle(hThread1);rn CloseHandle(hThread2);rnrn g_hEvent = CreateEvent(NULL, FALSE, TRUE, NULL); //创建一个自动重置的事件对象,初始化为有信号(触发态)rnrn Sleep(1000); //让主线程“睡眠”一秒 rn rn CloseHandle(g_hEvent);rn return 0;rn[/code]rnrn针对上面的这段代码,有时却会输出一些意想不到的结果:rnrn[color=#FF0000]Thread1 22170rnThread1 22171rnThread1 22172rnThread1 22173rnThread1 22174rnThread1 22175rnThread1 22176rnThread1 22177rnThread1 22178rnThread1 22179rnThread1 22180rnThread1 22181rnThread1 22182rnThread1 22183rnThread1 22184rnThread1 22185rnThread1 22186rnThread1 22187rnThread1 22188rnThread1 22189rnThread1 22190rnThread1 22191rnThread1 22192rnThread1 22193rnThread1 22194rnThread1 22195rnThread1 22196rnThread1 22197rnThread1 22198rnThread1 22199rnThread1 22200rnThread1 22201rnThread1 22202rnThread1 22203rnThread1 22204rnThread1 22205rnThread1 22206rnThread1 22207rnThread1 22208rnThread1 22209rnThread1 22210rnThread1 22211rnThread1 22212rnThread1 22213rnThread1 22214rnThread1 22215rnThread1 22216rnThread1 22217rnThread1 22218rnThread1 22219rnThread1 22220rnThread1 22221rnThread1 22222rnThread1 22223rnThread1 22224rnThread1 22225rnThread1 22226rnThread1 22227rnThread1 22228rnThread1 22229rnThread1 22230rnThread1 22231rnThread1 22232rnThread1 22233rnThread1 22234rnThread1 22235rnThread1 22236rnThread1 22237rnThread1 22238rnThread1 22239rnThread1 22240rnThread1 22241rnThread1 22242rnThread1 22243rnThread1 22244rnThread1 22245rnThread1 22246rnThread1 22247rnThread1 22248rnThread1 22249rnThread1 22250rnThread1 22251rnThread1 22252rnThread1 22253rnThread1 22254rnThread1 22255rnThread1 22256rnThread1 22257rnThread1 22258rnThread1 22259rnThread1 22260rnThread1 22261rnThread1 22262rnThread1 22263rnThread1 22264rnThread1 22265rnThread1 22266rnThread1 22267rnThread1 22268rnThread1 22269rnThread1 22270rnThread1 22271rnThread1 22272rnThread1 22273rnThread1 22274rnThread1 22275rnThread1 22276rnThread1 22277rnThread1 22278rnThread1 22279rnThread1 22280rnThread1 22281rnThread1 22282rnThread1 22283rnThread1 22284rnThread1 22285rnThread1 22286rnThread1 22287rnThread1 22288rnThread1 22289rnThread1 22290rnThread1 22291rnThread1 22292rnThread1 22293rnThread1 22294rnThread1 22295rnThread1 22296rnThread1 22297rnThread1 22298rnThread1 22299rnThread1 22300rnThread1 22301rnThread1 22302rnThread1 22303rnThread1 22304rnThread1 22305rnThread1 22306rnThread1 22307rnThread1 22308rnThread1 22309rnThread1 22310rnThread1 22311rnThread1 22312rnThread1 22313rnThread1 22314rnThread1 22315rnThread1 22316rnThread1 22317rnThread1 22318rnThread1 22319rnThread1 22320rnThread1 22321rnThread1 22322rnThread1 22323rnThread1 22324rnThread1 22325rnThread1 22326rnThread1 22327rnThread1 22328rnThread1 22329rnThread1 22330rnThread1 22331rnThread1 22332rnThread1 22333rnThread1 22334rnThread1 22335rnThread1 22336rnThread1 22337rnThread1 22338rnThread1 22339rnThread1 22340rnThread1 22341rnThread1 22342rnThread1 22343rnThread1 22344rnThread1 22345rnThread1 22346rnThread1 22347rnThread1 22348rnThread1 22349rnThread1 22350rnThread1 22351rnThread1 22352rnThread1 22353rnThread1 22354rnThread1 22355rnThread1 22356rnThread1 22357rnThread1 22358rnThread1 22359rnThread1 22360rnThread1 22361rnThread1 22362rnThread1 22363rnThread1 22364rnThread1 22365rnThread1 22366rnThread1 22367rnThread1 22368rnThread1 22369rnThread1 22370rnThread1 22371rnThread1 22372rnThread1 22373rnThread1 22374rnThread1 22375rnThread1 22376rnThread1 22377rnThread1 22378rnThread1 22379rnThread1 22380rnThread1 22381rnThread1 22382rnThread1 22383rnThread1 22384rnThread1 22385rnThread1 22386rnThread1 22387rnThread1 22388rnThread1 22389rnThread1 22390rnThread1 22391rnThread1 22392rnThread1 22393rnThread1 22394rnThread1 22395rnThread1 22396rnThread1 22397rnThread1 22398rnThread1 22399rnThread1 22400rnThread1 22401rnThread1 22402rnThread1 22403rnThread1 22404rnThread1 22405rnThread1 22406rnThread1 22407rnThread1 22408rnThread1 22409rnThread1 22410rnThread1 22411rnThread1 22412rnThread1 22413rnThread1 22414rnThread1 22415rnThread1 22416rnThread1 22417rnThread1 22418rnThread1 22419rnThread1 22420rnThread1 22421rnThread1 22422rnThread1 22423rnThread1 22424rnThread1 22425rnThread1 22426rnThread1 22427rnThread1 22428rnThread1 22429rnThread1 22430rnThread1 22431rnThread1 22432rnThread1 22433rnThread1 22434rnThread1 22435rnThread1 22436rnThread1 22437rnThread1 22438rnThread1 22439rnThread1 22440rnThread1 22441rnThread1 22442rnThread1 22443rnThread1 22444rnThread1 22445rnThread1 22446rnThread1 22447rnThread1 22448rnThread1 22449rnThread1 22450rnThread1 22451rnThread1 22452rnThread1 22453rnThread1 22454rnThread1 22455rnThread1 22456rnThread1 22457rnThread1 22458rnThread1 22459rnThread1 22460rnThread1 22461rnThread1 22462rnThread1 22463rnThread1 22464rnThread1 22465rnThread1 22466rnThread1 22466rnThread1 22467[/color]rnrn不知道怎么会输出上面的这个结果,大家帮忙解释一下! 论坛

android 编码那点

03-02

自做了一个android小程序,用于访问本地的一个web项目下的一个网页。rn用浏览器去访问该该网页能够正常显示中文,而用android程序通过流去读取该网页,rn中文会被 "南少林" 之类的代码替代。rnrnrn rn[code=Java]rn<%@ page language="java" import="java.util.*" contentType="text/html; charset=GBK" pageEncoding="GBK"%>rn<%@ taglib uri="/struts-tags" prefix="s" %>rnrnrnrn[/code]rnrnweb网页如上: 通过浏览器访问会显示如下语句rn[id:110,name:"太极宗师",time:28,id:111,name:"南少林",time:38,id:112,name:"楚留香",time:30] rnrnrnrn通过 android 程序读取网页信息代码如下:rn[code=Java]rn public static String getHtml(String textsrc) throws Exception rn rn URL url=new URL(textsrc);rn HttpURLConnection URLConnection=(HttpURLConnection) url.openConnection();rn URLConnection.setConnectTimeout(5000);rn URLConnection.setRequestMethod("GET");rn rn byte by[];rn if(URLConnection.getResponseCode()==200)rn rn InputStream inputStream=URLConnection.getInputStream();rn by=Inpututil.getinput(inputStream);rn inputStream.close();rn return new String(by);rn rn rn rn return null;rn rn[/code]rnrnrn[code=Java]rnpublic class Inpututil rnrn public static byte[] getinput(InputStream input) throws Exception rn ByteArrayOutputStream outputStream=new ByteArrayOutputStream();rn byte by[]=new byte[1024];rn int len=0;rn while((len=input.read())!=-1)rn rn input.read(by);rn outputStream.write(by);rn rn rn input.close();rn byte bt[]=outputStream.toByteArray();rn System.out.println(new String(bt,"GBK"));//想在这里输出与浏览器中一样的内容,可输出乱码,求解rn return bt;rn rnrnrn[/code]rnrn 论坛

没有更多推荐了,返回首页