日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

值类型 引用类型 堆栈 堆 之 异想

發(fā)布時(shí)間:2023/12/13 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 值类型 引用类型 堆栈 堆 之 异想 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
看了很多值類型 和 引用類型的文章(谷歌能搜索出來(lái)的) 看了越多疑問(wèn)越大,而這些資料中沒(méi)有具體的說(shuō)明。 問(wèn)題: 1、堆棧 和 堆 分別存于計(jì)算機(jī)的哪個(gè)硬件(CPU緩存,內(nèi)存,硬盤(pán))? 2、為什么只有值類型和引用類型? 3、為什么說(shuō)引用類型是指針? 4、堆棧必堆小小多少? 以下是個(gè)人的分析,不是權(quán)威結(jié)果。 1、堆棧 和 堆 分別存于計(jì)算機(jī)的哪個(gè)硬件(CPU緩存,內(nèi)存,硬盤(pán))? 使用排除法來(lái)看這個(gè)問(wèn)題 (1)CPU緩存 (2)內(nèi)存 (3)硬盤(pán) (3)可以排除堆棧的可能,因?yàn)?硬盤(pán)最慢 (2)最有可能存堆棧,因?yàn)?速度適中,且相對(duì)來(lái)說(shuō)存儲(chǔ)空間足夠大 (1)可能性很小,應(yīng)為僅幾年來(lái)CPU的緩存越來(lái)越大 但目前家用級(jí)別的CPU的1,2,3級(jí)緩存很少超過(guò)10MB(多核情況下每個(gè)核心分到的更少); 真像可能就是堆棧和堆都是放在內(nèi)存里的。 那么為什么堆棧比堆快呢? 個(gè)人認(rèn)為這情況和hashtable與list等數(shù)據(jù)容器的差異,差不多。 存取方式?jīng)Q定的。 堆棧:只能存取值類型,且先進(jìn)先出,不夠的時(shí)候直接壓棧(就像"向右看起"的命令一樣) --簡(jiǎn)單快捷 堆:首先,堆的分配模式會(huì)存在碎片,并不是連續(xù)性的(這里直的是多個(gè)對(duì)象,找到一個(gè)適合的內(nèi)存空間就把對(duì)象放進(jìn)去,就像家居擺放物件一樣,有時(shí)候不貼個(gè)紙條的話,得找半天)。 2、為什么只有值類型和引用類型? 這個(gè)我覺(jué)得追溯到本源比較好解釋,就是CPU只能進(jìn)行數(shù)學(xué)計(jì)算。(看下匯編代碼會(huì)好理解些) 值類型:就是數(shù)字,CPU可以直接進(jìn)行運(yùn)算。 引用類型:最終指向值類型的指針。object是指針,object的ToString的函數(shù)還是一個(gè)指針,ToString內(nèi)有String類型還是指針,最終指向一個(gè)Char[] 字符集合 (注,我對(duì)String的理解就是Char[])。 所以對(duì)象無(wú)法直接進(jìn)行運(yùn)算,只能通過(guò)指針找到能運(yùn)算的部分,再進(jìn)行運(yùn)算。這也就是為啥只有2個(gè)類型了,一個(gè)是值用于運(yùn)算,一個(gè)是指針,指向需要運(yùn)算的地方。 3、為什么說(shuō)引用類型是指針? 由上可知,引用類型是指針必然性。 一個(gè)Class內(nèi)除了Int32等 值類型外其他皆是指針,委托,函數(shù),函數(shù)內(nèi)的對(duì)象,屬性,事件 都是指針。 根據(jù)這種特性,指針(引用類型)作為參數(shù)傳遞,出來(lái)的時(shí)候會(huì)根據(jù)函數(shù)內(nèi)的改變而改變,而值要作為參數(shù)輸入并輸出的話就要ref了。 (注: 個(gè)人發(fā)現(xiàn) DateTime 作為參數(shù)時(shí)具有值類型的特征) 4、堆棧必堆小小多少? 未知,希望有知道的朋友能給出測(cè)試方法或者結(jié)果 我的推測(cè)是既然是在內(nèi)存,必然沒(méi)有限制,除非人為的限制 我使用線程測(cè)試內(nèi)存上限時(shí)發(fā)現(xiàn)沒(méi)有具體的上限。我的是64位+8G內(nèi)存的筆記本以下是測(cè)試結(jié)果:(線程內(nèi)分別創(chuàng)建class和sturct) X86: 一個(gè)應(yīng)用程序只能達(dá)到1300多一點(diǎn)的線程,再也上不去了,提交內(nèi)存約1440k class:運(yùn)行穩(wěn)定。sturct:大約2分鐘 內(nèi)存溢出 X64:一個(gè)應(yīng)用程序只能達(dá)到8000多的線程,提交內(nèi)存約10000k(還能繼續(xù)) class:運(yùn)行穩(wěn)定。sturct:行穩(wěn)定 最終 我的結(jié)論:在C#里class 和sturct 如果真的是一個(gè)分配在堆,一個(gè)分配在堆棧,那么堆棧和堆的空間大小沒(méi)有區(qū)別,只存在速度的區(qū)別 以下是測(cè)試代碼: using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
for (var i = 0; i < 10000; i++)
{
Thread th = new Thread(() =>
{
abc a = new abc(1);
});
th.Start();
}
Console.ReadKey();
}
}
struct abc
{
public abc(Int32 x)
{
ds = String.Empty;
Test();
}
String ds;
private void Test()
{
while (true)
{
ds += "A";
Thread.Sleep(1000);
}
}
}
class bc
{
public bc(Int32 x)
{
ds = String.Empty;
Test();
}
String ds;
private void Test()
{
while (true)
{
ds += "A";
Thread.Sleep(1000);
}
}
}
} IL:

class 的

// 代碼大小 28 (0x1c) .maxstack 8 IL_0000: ldarg.0 IL_0001: call instance void [mscorlib]System.Object::.ctor() IL_0006: nop IL_0007: nop IL_0008: ldarg.0 IL_0009: ldsfld string [mscorlib]System.String::Empty IL_000e: stfld string ConsoleApplication1.bc::ds IL_0013: ldarg.0 IL_0014: call instance void ConsoleApplication1.bc::Test() IL_0019: nop IL_001a: nop IL_001b: ret } // end of method bc::.ctor sturct 的 // 代碼大小 20 (0x14) .maxstack 8 IL_0000: nop IL_0001: ldarg.0 IL_0002: ldsfld string [mscorlib]System.String::Empty IL_0007: stfld string ConsoleApplication1.abc::ds IL_000c: ldarg.0 IL_000d: call instance void ConsoleApplication1.abc::Test() IL_0012: nop IL_0013: ret } // end of method abc::.ctor 堆棧容量測(cè)試: using System; using System.Threading; namespace ConsoleApplication1 {class Program{static void Main(string[] args){String txt = System.IO.File.ReadAllText("demo.txt");//一個(gè)3.11MB的文本 Thread th = new Thread(() =>{abc a = new abc(1);for (var i = 0; i < 1000; i++){a.ds += txt;}});th.Start();Console.ReadKey();}}struct abc{public abc(Int32 x){ds = String.Empty;}public String ds;}}

測(cè)試結(jié)果:X64 能 提交內(nèi)存3000K以上

?


我的結(jié)論和想法是這樣的:

首先我是站在CPU的角度去思考的。

1、堆棧 堆 可能都是一樣的指針,他們本身只是數(shù)據(jù)容器。

2、他們的區(qū)別在于存取方式不一致導(dǎo)致的存取速度不一樣。

3、堆棧 和堆 沒(méi)有具體大小,除非人為設(shè)置,且很有可能由CLR或者編譯器動(dòng)態(tài)選擇數(shù)據(jù)容器。(畢竟我只能看到IL,看不到先X86反編譯匯編)

4、值類型傳參實(shí)為傳值,引用類型傳參實(shí)為傳地址(指針),這也是堆棧和堆數(shù)據(jù)使用上的區(qū)別。CPU對(duì)堆棧的態(tài)度是拿來(lái)就用,對(duì)堆就是找到再用。

通過(guò) Wiz 發(fā)布



轉(zhuǎn)載于:https://www.cnblogs.com/tianjing/archive/2012/07/03/2574577.html

總結(jié)

以上是生活随笔為你收集整理的值类型 引用类型 堆栈 堆 之 异想的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。