前幾天公眾號里有位兄弟看了幾篇文章之后,也準備用windbg試試看,結(jié)果這一配就花了好幾天,(づ╥﹏╥)づ,我想也有很多躍躍欲試的朋友在配置的時候肯定會遇到這樣和那樣的問題,所以我覺得有必要整理一下,讓大家少走彎路。
現(xiàn)在安裝windbg越來越麻煩,還要安裝Windows 10 SDK,很多人就栽在這里,其實大家可以直接在網(wǎng)上找一鍵打包的windbg 6.0版本即可,才30多M,調(diào)生產(chǎn)調(diào)本地都很方便,順帶還可以練練SOS命令。
云盤:https://pan.baidu.com/s/1VqXVIGVHxAZVPNds1525Jg 提取碼:mahg
外網(wǎng):http://www.33lc.com/soft/96743.html
解壓打開會有一個x64和x86文件夾,很顯然,32位的程序用x86下的windbg調(diào)試,64位的程序用x64的windbg調(diào)試,如下圖:
我比較喜歡用64bit程序,所以這里使用64位的windbg。
符號其實就是pdb文件,我們在debug模式下編譯項目都會看到這個,它的作用會對dll進行打標,這樣在調(diào)試時通過pdb就能看到局部變量,全局變量,行號等等其他信息,在FCL類庫中的pdb文件就放在微軟的公有服務器上,SRV*C:\mysymbols*http://msdl.microsoft.com/download/symbols。
很多時候大家都是事后調(diào)試,所以需要在生產(chǎn)上抓一個dump文件,為了將dump文件逆向到clr上的運行時狀態(tài),你必須要尋找到當時運行程序clr版本,同時也要找到對應clr版本的sos.dll,他們通常是在一起的,sos 就是 你 和 clr交互的渠道,很多人都卡在尋找正確版本的sos和clr版本上。。。如果不清楚,我可以畫張圖。
有了這個前置基礎(chǔ),接下來就可以在windows和centos上進行配置實踐了。。。
為了演示,我先上一段簡單的代碼:
static void Main(string[] args)
{
var info="hello world!";
Console.WriteLine(info);
Console.ReadLine();
}
在netcore中,clr的名字變成了 coreclr.dll,路徑: C:\Program Files\dotnet\shared\Microsoft.NETCore.App.1.3
netcore3.0開始,sos就沒有放在版本號文件下了,詳見 SOS_README.md 內(nèi)容。
SOS and other diagnostic tools now ship of band and work with any version of the .NET Core runtime.
SOS has moved to the diagnostics repo here: https://github.com/dotnet/diagnostics.git.
Instructions to install SOS: https://github.com/dotnet/diagnostics#installing-sos.
看了上面文檔,大概意思就是說老版本的windbg,需要通過小工具dotnet-sos 自己生成一個sos.dll,那就按照文檔來吧
PS C:\WINDOWS\system32> dotnet tool install -g dotnet-sos
You can invoke the tool using the following command: dotnet-sos
Tool 'dotnet-sos' (version '3.1.122203') was successfully installed.
PS C:\WINDOWS\system32> dotnet-sos install
Installing SOS to C:\Users\hxc\.dotnet\sos from C:\Users\hxc\.dotnet\tools\.store\dotnet-sos\3.1.122203\dotnet-sos\3.1.122203\tools\netcoreapp2.1\any\win-x64
Installing over existing installation...
Creating installation directory...
Copying files...
Execute '.load C:\Users\hxc\.dotnet\sos\sos.dll' to load SOS in your Windows debugger.
Cleaning up...
SOS install succeeded
PS C:\WINDOWS\system32>
仔細看輸出,sos.dll 已經(jīng)生成好了,接下來在任務管理器中生成一個dump文件,然后使用 .load 命令把 coreclr 和 sos 加載進去即可。
.load C:\Users\hxc\.dotnet\sos\sos.dll
.load C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.3\coreclr.dll
最后我們抓一下 info 變量在堆上的分布。
0:000> ~0s
ntdll!ZwReadFile+0x14:
00007ff8`3228aa64 c3 ret
0:000> !clrstack -l
OS Thread Id: 0x41d4 (0)
000000246097EA40 00007FFF89C50F97 Error: Fail to initialize CoreCLR 80131022
ConsoleApp5.Program.Main(System.String[])
LOCALS:
0x000000246097EA68=0x0000021d8141aba8
0:000> !do 0x0000021d8141aba8
Name: System.String
MethodTable: 00007fff89cd1e18
EEClass: 00007fff89cc2128
Size: 46(0x2e) bytes
File: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.3\System.Private.CoreLib.dll
String: hello world!
Fields:
MT Field Offset Type VT Attr Value Name
00007fff89c1b1e8 4000242 8 System.Int32 1 instance 12 _stringLength
00007fff89c18000 4000243 c System.Char 1 instance 68 _firstChar
00007fff89cd1e18 4000244 110 System.String 0 static 0000021d81411360 Empty
好了,windows上的netcore調(diào)試就這么簡單,希望這些配置能節(jié)省您的時間。
framework程序比netcore配置要方便的多,不需要自己去生成sos了,如下代碼所示:
64位程序加載路徑
.load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\sos.dll
.load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
32位程序加載路徑
.load C:\Windows\Microsoft.NET\Framework\v4.0.30319\sos.dll
.load C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
首先要明白,對于linux內(nèi)核windbg就失效了,那怎么調(diào)試呢? 有兩種方式。
這個工具的地方在于,sos和clr都不需要你配置,直接使用它生成dump,然后直接調(diào)試,方便至極,下面看看怎么安裝,開兩個terminal,如下代碼:
terminal 1:
[root@10-25-198-96 data]# dotnet build
[root@10-25-198-96 netcoreapp3.1]# dotnet data.dll
hello world
terminal 2:
[root@10-25-198-96 cs2]# ps -ef | grep dotnet
root 31555 31247 0 22:28 pts/0 00:00:00 dotnet cs2.dll
root 32112 31995 0 22:29 pts/2 00:00:00 grep --color=auto dotnet
[root@10-25-198-96 cs2]# dotnet tool install -g dotnet-dump
You can invoke the tool using the following command: dotnet-dump
Tool 'dotnet-dump' (version '3.1.122203') was successfully installed.
[root@10-25-198-96 cs2]# export PATH=$PATH:$HOME/.dotnet/tools
[root@10-25-198-96 cs2]# dotnet-dump collect --process-id 31555
Writing full to /cs2/core_20200508_223204
Complete
可以看到dump文件已經(jīng)好了 /cs2/core_20200508_223204 ,接下來用 dotnet-dump 對dump文件調(diào)試。
[root@10-25-198-96 cs2]# dotnet-dump analyze /cs2/core_20200508_223204
Loading core dump: /cs2/core_20200508_223204 ...
Ready to process analysis commands. Type 'help' to list available commands or 'help [command]' to get detailed help on a command.
Type 'quit' or 'exit' to exit the session.
> clrstack -l
OS Thread Id: 0x7b43 (0)
Child SP IP Call Site
00007FFDFCABF2D0 00007fb0397af7fd [InlinedCallFrame: 00007ffdfcabf2d0] Interop+Sys.ReadStdin(Byte*, Int32)
00007FFDFCABF2D0 00007fafbebbb4db [InlinedCallFrame: 00007ffdfcabf2d0] Interop+Sys.ReadStdin(Byte*, Int32)
00007FFDFCABF2C0 00007FAFBEBBB4DB ILStubClass.IL_STUB_PInvoke(Byte*, Int32)
00007FFDFCABF9D0 00007FAFBECF844D System.Console.ReadLine()
00007FFDFCABF9E0 00007FAFBEBB037D cs2.Program.Main(System.String[]) [/cs2/Program.cs @ 13]
LOCALS:
0x00007FFDFCABF9F0=0x00007faf980081d8
00007FFDFCABFD08 00007fb037fc0f7f [GCFrame: 00007ffdfcabfd08]
00007FFDFCAC01F0 00007fb037fc0f7f [GCFrame: 00007ffdfcac01f0]
> dumpobj 0x00007faf980081d8
Name: System.String
MethodTable: 00007fafbec30f90
EEClass: 00007fafbeb9e1b0
Size: 44(0x2c) bytes
File: /usr/share/dotnet/shared/Microsoft.NETCore.App/3.1.3/System.Private.CoreLib.dll
String: hello world
Fields:
MT Field Offset Type VT Attr Value Name
00007fafbec2a0e8 400022a 8 System.Int32 1 instance 11 _stringLength
00007fafbec26f00 400022b c System.Char 1 instance 68 _firstChar
00007fafbec30f90 400022c 108 System.String 0 static 00007faf97fff360 Empty
>
就這么簡單,不過這個工具雖好,但是不能調(diào)試非托管堆,而且命令也不是太多,當然夠我們平時用了。
要想實現(xiàn)windbg級別的調(diào)試,可以使用lldb調(diào)試器,這個非常強大,這里我也來介紹一下吧。
lldb是使用C++寫的,也可以在 https://github.com/dotnet/diagnostics/blob/master/documentation/building/linux-instructions.md 尋找安裝辦法。
sudo yum install centos-release-SCL epel-release
sudo yum install cmake cmake3 gcc gcc-c++ gdb git libicu libunwind make python27 tar wget which zip
cd $HOME
git clone https://github.com/dotnet/diagnostics.git
$HOME/diagnostics/documentation/lldb/centos7/build-install-lldb.sh
一陣抽搐后就安裝好了,從下面可以看到目前版本是3.9.1。
[root@10-25-198-96 cs2]# lldb -v
lldb version 3.9.1 ( revision )
跟windbg一樣,你需要生成一個sos.dll 。。。 同樣也是使用 dotnet-sos 生成。
[root@10-25-198-96 cs2]# dotnet tool install -g dotnet-sos
You can invoke the tool using the following command: dotnet-sos
Tool 'dotnet-sos' (version '3.1.122203') was successfully installed.
[root@10-25-198-96 cs2]# dotnet-sos install
Installing SOS to /root/.dotnet/sos from /root/.dotnet/tools/.store/dotnet-sos/3.1.122203/dotnet-sos/3.1.122203/tools/netcoreapp2.1/any/linux-x64
Installing over existing installation...
Creating installation directory...
Copying files...
Updating existing /root/.lldbinit file - LLDB will load SOS automatically at startup
Cleaning up...
SOS install succeeded
從上面信息看,sos 是安裝在 /root/.dotnet/sos 目錄下,同時也看到在lldb啟動的時候會自動加載sos.dll 。。。
每個dotnet版本下都有一個createdump程序,可以用它生成dump文件,具體配置文檔可以參見:
https://github.com/dotnet/diagnostics/blob/master/documentation/debugging-coredump.md
https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/botr/xplat-minidump-generation.md#configurationpolicy
[root@10-25-198-96 cs2]# ps -ef | grep dotnet
root 31555 31247 0 22:28 pts/0 00:00:00 dotnet cs2.dll
root 32112 31995 0 22:29 pts/2 00:00:00 grep --color=auto dotnet
[root@10-25-198-96 cs2]# find / -name createdump
/usr/share/dotnet/shared/Microsoft.NETCore.App/3.1.3/createdump
[root@10-25-198-96 3.1.3]# ./createdump 31555 -f /lldb/test.dump
Writing minidump with heap to file /lldb/test.dump
Written 84692992 bytes (20677 pages) to core file
[root@10-25-198-96 3.1.3]# lldb --core /lldb/test.dump
(lldb) target create --core "/lldb/test.dump"
Core file '/lldb/test.dump' (x86_64) was loaded.
(lldb) clrstack -l
OS Thread Id: 0x7b43 (1)
00007FFDFCABF9E0 00007FAFBEBB037D cs2.Program.Main(System.String[]) [/cs2/Program.cs @ 13]
LOCALS:
0x00007FFDFCABF9F0=0x00007faf980081d8
00007FFDFCABFD08 00007fb037fc0f7f [GCFrame: 00007ffdfcabfd08]
00007FFDFCAC01F0 00007fb037fc0f7f [GCFrame: 00007ffdfcac01f0]
(lldb) dumpobj 0x00007faf980081d8
Name: System.String
MethodTable: 00007fafbec30f90
EEClass: 00007fafbeb9e1b0
Size: 44(0x2c) bytes
File: /usr/share/dotnet/shared/Microsoft.NETCore.App/3.1.3/System.Private.CoreLib.dll
String: hello world
Fields:
MT Field Offset Type VT Attr Value Name
00007fafbec2a0e8 400022a 8 System.Int32 1 instance 11 _stringLength
00007fafbec26f00 400022b c System.Char 1 instance 68 _firstChar
00007fafbec30f90 400022c 108 System.String 0 static 00007faf97fff360 Empty
(lldb)
可以看到,通過lldb也可以直接打入clr內(nèi)部啦。。。
我覺得這篇文章肯定能給很多朋友節(jié)省不少的時間,想起朱一旦的那句話:有錢人的快樂,就是這么樸實無華且枯燥, 哈哈~
有使用數(shù)據(jù)集合操作的DevExtreme ASP.NET MVC控件都有DataSource()方法,與其他控制方法不同,DataSource()在DevExtreme JavaScript API中沒有直接對應物,盡管它的用途類似于DevExtreme數(shù)據(jù)層中的 Store。您可以使用 DataSource() 方法來配置來自不同來源的數(shù)據(jù)訪問:
數(shù)據(jù)綁定控件(PivotGrid 除外)也具有 DataSourceOptions() 方法,它公開了一個構(gòu)建器,用于配置初始排序、過濾、分組和其他數(shù)據(jù)整形操作,構(gòu)建器的方法具有本節(jié)中描述的 JavaScript API 對應項。
DevExtreme Complete Subscription官方最新版免費下載試用,歷史版本下載,在線文檔和幫助文件下載-慧都網(wǎng)
您可以將DevExtreme ASP.NET MVC 控件綁定到 CLR 對象的集合:Array、List 或 IEnumerable。
這些集合…
集合作為 ArrayStore 傳遞給客戶端,請注意,集合數(shù)據(jù)應該是 JSON 可序列化的。
示例:將控件綁定到數(shù)組
Razor C#
@(Html.DevExtreme().Chart()
.DataSource(new[] {
new { Day="Monday", Oranges=3 },
new { Day="Tuesday", Oranges=2 },
new { Day="Wednesday", Oranges=3 },
new { Day="Thursday", Oranges=4 },
new { Day="Friday", Oranges=6 },
new { Day="Saturday", Oranges=11 },
new { Day="Sunday", Oranges=4 }
})
)
Razor VB
@(Html.DevExtreme().Chart() _
.DataSource({
New With {.Day="Monday", .Oranges=3},
New With {.Day="Tuesday", .Oranges=2},
New With {.Day="Wednesday", .Oranges=3},
New With {.Day="Thursday", .Oranges=4},
New With {.Day="Friday", .Oranges=6},
New With {.Day="Saturday", .Oranges=11},
New With {.Day="Sunday", .Oranges=4}
})
)
示例:將控件綁定到模型
本示例代碼展示了如何將 MultiView 控件綁定到 Model。
View
Razor C#
@model List<DevExtreme.MVC.Demos.Models.Store>
@(Html.DevExtreme().MultiView()
.DataSource(Model)
)
Razor VB
@ModelType List(Of DevExtreme.MVC.Demos.Models.Store)
@(Html.DevExtreme().MultiView() _
.DataSource(Model)
)
Model
C#
namespace DevExtreme.MVC.Demos.Models.SampleData {
public partial class SampleData {
public static Store[] Stores=new[] {
new Store {
ID=1,
CompanyName="SuprMart",
Address="702 SW 8th Street",
City="Bentonville",
},
new Store {
ID=2,
CompanyName="El'Depot",
Address="2455 Paces Ferry Road NW",
City="Atlanta",
},
new Store {
ID=3,
CompanyName="K&S Music",
Address="1000 Nicllet Mall",
City="Minneapolis",
}
};
}
}
VB
Namespace DevExtreme.MVC.Demos.Models.SampleData
Partial Public Class SampleData
Public Shared Stores As Store()={
New Store With {
.ID=1,
.CompanyName="SuprMart",
.Address="702 SW 8th Street",
.City="Bentonville"
},
New Store With {
.ID=2,
.CompanyName="El'Depot",
.Address="2455 Paces Ferry Road NW",
.City="Atlanta"
},
New Store With {
.ID=3,
.CompanyName="K&S Music",
.Address="1000 Nicllet Mall",
.City="Minneapolis"
}
}
End Class
End Namespace
Controller
C#
using DevExtreme.MVC.Demos.Models.SampleData;
namespace DevExtreme.MVC.Demos.Controllers {
public class MultiViewController : Controller {
public ActionResult Overview() {
return View(SampleData.Stores);
}
}
}
VB
Imports DevExtreme.MVC.Demos.Models.SampleData
Namespace DevExtreme.MVC.Demos.Controllers
Public Class MultiViewController
Inherits Controller
Public Function Overview() As ActionResult
Return View(SampleData.Stores)
End Function
End Class
End Namespace
DataSource 方法重載接受 string[] 鍵參數(shù),因此您的代碼如下所示:
C#
.DataSource(Model.YourCollection, "KeyFieldName")
VB
.DataSource(Model.YourCollection, "KeyFieldName")
DevExtreme
DevExtreme擁有高性能的HTML5 / JavaScript小部件集合,使您可以利用現(xiàn)代Web開發(fā)堆棧(包括React,Angular,ASP.NET Core,jQuery,Knockout等)構(gòu)建交互式的Web應用程序。從Angular和Reac,到ASP.NET Core或Vue,DevExtreme包含全面的高性能和響應式UI小部件集合,可在傳統(tǒng)Web和下一代移動應用程序中使用。 該套件附帶功能齊全的數(shù)據(jù)網(wǎng)格、交互式圖表小部件、數(shù)據(jù)編輯器等。
起棧想必會聽到這樣幾個關(guān)鍵詞:后進先出,先進后出,入棧,出棧。
棧這種數(shù)據(jù)結(jié)構(gòu),數(shù)組完全可以代替其功能。
但是存在即是真理,其目的就是避免暴露不必要的操作。
如角色一樣,不同的情景或者角色擁有不同的操作權(quán)限。
那我們來了解一下棧,棧是一種線性數(shù)據(jù)結(jié)構(gòu),并且只能從一端壓入或者彈出=添加或者刪除。
基于數(shù)組實現(xiàn)的棧是順序棧,基于鏈表實現(xiàn)的鏈式棧。
注釋說的很明白:這是一個基于數(shù)組實現(xiàn)的順序棧,其入棧復雜度O(n),出棧復雜度為O(1)
// A simple stack of objects. Internally it is implemented as an array,
// so Push can be O(n). Pop is O(1).
[DebuggerTypeProxy(typeof(System.Collections.Stack.StackDebugView))]
[DebuggerDisplay("Count={Count}")]
[System.Runtime.InteropServices.ComVisible(true)]
[Serializable]
public class Stack : ICollection, ICloneable {
private Object[] _array; // Storage for stack elements
[ContractPublicPropertyName("Count")]
private int _size; // Number of items in the stack.
private int _version; // Used to keep enumerator in sync w/ collection.
[NonSerialized]
private Object _syncRoot;
private const int _defaultCapacity=10;
public Stack() {
_array=new Object[_defaultCapacity];
_size=0;
_version=0;
}
入棧:我們也看到這個是基于數(shù)組并且支持的那個太擴容的棧,默認大小圍為10,當存滿之后就會兩倍擴容。
// Pushes an item to the top of the stack.
//
public virtual void Push(Object obj) {
//Contract.Ensures(Count==Contract.OldValue(Count) + 1);
if (_size==_array.Length) {
Object[] newArray=new Object[2*_array.Length];
Array.Copy(_array, 0, newArray, 0, _size);
_array=newArray;
}
_array[_size++]=obj;
_version++;
}
正如注釋中提到的,入棧復雜度可以達到O(n),出棧可以是O(1)
so Push can be O(n). Pop is O(1).
出棧Pop,復雜度為O(1)很好理解,
上面提到的動態(tài)棧是操作受限的數(shù)組,并且不會產(chǎn)生新的內(nèi)存申請或者數(shù)據(jù)的搬移
我們只要是獲取到最后一個,然后彈出(也就是刪除)即可。
入棧Push,我們接下來分析一下出棧為什么復雜度為O(n):
前面有一篇《算法復雜度》 https://www.cnblogs.com/sunchong/p/9928293.html ,提到過:最好、最壞、平均
對于下面的入棧代碼:
最好情況時間復雜度:不會有擴容和數(shù)據(jù)遷移,所以直接追加即可,復雜度為O(1)
最壞情況時間復雜度:需要擴容后并且搬移原來n個數(shù)據(jù),然后再插入新的數(shù)據(jù),復雜度為 O(n)
那么平均時間復雜度是多少呢?這里需要結(jié)合攤還分析法,進行復雜度分析。為什么這里要使用攤還分析法呢?
先耐心地看看其定義:
分析一個操作序列中所執(zhí)行的所有操作的平均時間分析方法。
與一般的平均分析方法不同的是,它不涉及概率的分析,可以保證最壞情況下每個操作的平均性能。
總結(jié)一下攤還分析:執(zhí)行的所有操作的平均時間,不扯概率。
我們可以拿攤還分析來直接分析:
public virtual void Push(Object obj)
{
//Contract.Ensures(Count==Contract.OldValue(Count) + 1);
if (_size==_array.Length)
{
Object[] newArray=new Object[2*_array.Length];
Array.Copy(_array, 0, newArray, 0, _size);
_array=newArray;
}
_array[_size++]=obj;
_version++;
}
入棧的最壞情況復雜度是O(n),但是這個最壞情況時間復雜度是在n+1次插入的時候發(fā)生的,
剩下的n次是不需要擴容搬移數(shù)據(jù),只是簡單的入棧 O(1),所以均攤下來的復雜度是O(1)。
那么為什么微軟的工程師在備注里寫下push復雜度是O(n)?--這里指的是空間復雜度O(n)
棧這種數(shù)據(jù)結(jié)構(gòu)的應用有很多場景,其中一種就是我們的線程棧或者說函數(shù)棧。
當開啟一個線程時,Windows系統(tǒng)為每個線程分配一個1M大小的線程棧。分配這個用來干什么呢?
存儲方法中的參數(shù)和變量。趁這個機會,我們了解一下CLR的內(nèi)存模型。
首先對于C#代碼是如何編程機器代碼的呢?
c#代碼 -> 編譯器 -> IL -> JIT -> CPU指令
這段代碼也很簡單,就是在Main方法中調(diào)用了GetCode()方法,其他的都是一些臨時變量。
static void Main(string[] args)
{
string parentCode="PI001";
string newCode=string.Empty;
newCode=GetCode(parentCode);
}
static string GetCode(string sourceCode)
{
string currentMaxCode="001001";
string newCode=$"{sourceCode}{currentMaxCode}";
return newCode;
}
首先線程會分配1M內(nèi)存用于存儲臨時變量和參數(shù);
進入Main方法時,會將參數(shù)和返回地址依次壓棧
static void Main(string[] args)
string parentCode="PI001";
string newCode=string.Empty;
接下來開始進入到 GetCode() 方法,此時與之前一樣壓入?yún)?shù)和返回地址
string currentMaxCode="001001";
string newCode=$"{sourceCode}{currentMaxCode}";
既然說到了棧,那我們不得不再說一下托管堆,再來一段代碼圖解:
這是父類和子類的具體代碼,可以略過此處。
我們隱藏這些方法的具體實現(xiàn),只預覽他們的之間的關(guān)系:
接下來,線程即將進入到下面的這個方法:
void GetProduct()
{
BaseProduct p;
string sourceCode;
p=new Product();
sourceCode=p.GetCode();
sourceCode=Product.GetNewCode(sourceCode);
}
JIT在編譯到此方法前會注意到這個方法所有的引用類型,
并向CLR發(fā)出通知,加載程序集,在托管對中創(chuàng)建相關(guān)的類型對象數(shù)據(jù)結(jié)構(gòu)。
這也就是我們所能理解的靜態(tài)字段為什么不是在實例化的時候創(chuàng)建,
而是在這個類型創(chuàng)建的時候就一直存在。
這其實就是兩個概念,靜態(tài)資源是屬于類結(jié)構(gòu)的,而實例資源是屬于實例本身。
下面的圖忽略String類型,因為String類型是常用類型可能在之前就已經(jīng)創(chuàng)建好了,
類型對象包括:對象指針、同步塊索引、靜態(tài)資源、方法表,像下面這樣:
BaseProduct p;
string sourceCode;
方法變量入棧,并且引用類型初始化為null
p=new Product();
實例化Product ,托管堆創(chuàng)建Product對象,并將這個對象的指針指向Product類型。
將線程棧中的變量p指針,指向新創(chuàng)建的Product對象。
sourceCode=p.GetCode();
JIT找到這個變量p的Product對象,再找到對應的Product類型,表中找到此方法GetCode();
當然這個方法實際是父類的方法,所以JIT會一直向上找,直到找到為止。
圖中是個虛擬路線,計算結(jié)果賦值給 string sourceCode
sourceCode=Product.GetNewCode(sourceCode);
和上一步類似,只不過這次是調(diào)用的靜態(tài)方法。發(fā)出類型Product,靜態(tài)方法是GetNewCode()
以上內(nèi)容就是 JIT、CLR、線程棧、托管堆的一些運行時關(guān)系。
*請認真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。