由c#的值类型与引用类型说开去
之前一直被灌輸,C#分值類型和引用類型,在程序運行時,它們分別存在棧(Stack) 和堆(Heap)上。這也是面試經典問題了,但其實其中存在很大的誤解。比如某個實例對象中有一個Int型成員。當這個實例初始化并被賦值后,該成員是在 堆中還是棧中?如果始終在棧中顯然無法解釋,因為棧中數據離開作用域就被釋放了。
真實的概念應該是,.net在運行中需要4類數據,值類型,引用類型,指向對象實例(即引用類型)的指針,以及指令(方法)。這些東西中除引用類型外,在執行某個方法時會按順序放入棧中,而方法結束退出時即離開作用域時,會自動從棧上釋放相關數據。
這里有兩篇文章詳細介紹了.net如何在執行方法時使用棧和堆,相當詳細:
http://www.cnblogs.com/c2303191/articles/1065675.html
http://www.cnblogs.com/lemontea/p/3159282.html
?
所以最終的解釋是,一個程序,啟動時就相當于啟動了一個main函數的方法(Web程序由IIS host,本質上是一樣的)。在運行時實例化的引用類型及該實例內部的成員數據其實都是放在堆上的,但執行中具體要被調用的變量,方法參數,指針,指令則 會放入棧中使用,目的是滿足值類型的隔離性以及在脫離作用域時自動釋放。
?
那為何需要分為棧和堆呢?能否相互替代呢?答案顯然是不能的。
棧是在某個應用程序(進程)啟動前就被分配好最大容量的,放入棧的內容都必須是確定其大小的,所以只能是值類型,指針或指令。沒有堆的配合無法進行面向對象的編程。
只有堆的話雖然什么都可以放,但是也有很多缺陷,主要有3點:
1.棧分配內存比堆快:棧中存入的數據大小是確定的,只需要簡單的地址偏移即可。
2.堆不會靠內存機制自動釋放,容易產生內存泄露。
3.堆會產生內存碎片。
針對2和3,.net靠垃圾回收(GC)來自動釋放托管對象以及壓縮內存碎片,但頻繁GC會導致程序性能很差,開銷很大。
所以只有當棧和堆互補時,.net的性能和安全性才是最優的。
轉載于:https://www.cnblogs.com/Vincent-Sun/p/5639591.html
總結
以上是生活随笔為你收集整理的由c#的值类型与引用类型说开去的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 迭代开发个人总结20160702
- 下一篇: 日期处理(转)