C_Sharp 板


LINE

同討論串前一篇的講法很一知半解(或者說,其實連正解的五分之一都不到), 且聽我道來。 作業系統配置記憶體給應用程式後,應用程式要怎麼使用這些記憶體, 基本上都是應用程式自己的事務,作業系統不會去干涉的。 就一般應用程式架構設計來說,會把作業系統下來的記憶體分為幾類: 程式碼空間,堆疊,靜態資料,堆積;在台灣一般學校裡傳授使用MASM的 16-bit X86組合語言裡,宣告段落時,對應的只有前三樣,.code,.stack, .data,嚴格說來,.data就同時包含了靜態資料與堆積。去問只會組語而不 明白高階程式語言程式中記憶體配置機制的人,得到不知道堆積heap是什麼 的答案也不奇怪。 先講原生機械碼平台上的情形: 一般高階語言寫出來的程式,編譯好後,程式中編譯前定義的靜態資料佔用的 記憶體空間都是固定的,但是程式中動態配置的記憶體仍然要佔用空間。這些 不見得會被持續佔用著,也不見得是固定大小的,通通由保留給heap的記憶體 空間來支應。在高階語言程式中會有編譯器廠商提供包含heap manager的執行 期程式庫,由裡頭的heap manager來應付程式語言中對動態記憶體配置與釋放 的要求。配置給程式作為動態記憶體塊使用的記憶體空間,會從heap中的可用 空間被劃分出來,標示為已使用,不可以被重複配置給其他動態記憶體配置要 求,直到這個動態記憶體塊被釋放,heap manager才會再把它列入可用空間中。 如Visual C++、Borland C++、Delphi,雖然各個編譯器的heap manager設計 各有出入,大體上都是用linked list在管理這些大大小小的可用空間跟已配置 記憶體塊。以C++為例,物件的記憶體配置,auto的都是來自stack,static的 來自靜態資料空間,dynamic的就都是執行期從heap動態配置出來的,所有new 出來的物件都是動態物件,都從heap配置記憶體。 Stack中是不會放任何程式編譯好時就預先定義好的資料的,學過組語的人會講 「早期的C, 程式一開始即宣告好的字串就是 Stack了」,實在是有嚴重誤解 啊。也許你可以設計一個編譯器,刻意把宣告好的字串放在stack裡頭,但是 後果會如何,只要遞迴次數夠多次、stack的區域變數佔用的空間夠大,就很 清楚了。 細節不深入太多。但是這樣子的設計衍生出來的一個程式維護性問題是,凡是 被配置出來的動態記憶體塊,最後都要被釋放,才能夠再給其他的動態記憶體 配置要求所使用。如果這些動態配置出來的記憶體都沒釋放,即使程式中已經 不再參考使用這些記憶體塊,它們也不能被回收使用。相對的,如果一個記憶 體塊還被參考使用著,卻因為程式設計者的疏忽而被釋放,然後被其他動態記 憶體配置要求所使用,就會發生存取錯誤資料的情形。所以才衍生出GC來。 在原生機械碼平台上有GC的程式開發環境沒有成為顯學,但是Java/.NET在設 計時把GC當成了預設行為。有GC後,寫程式還是要跟heap manager打交道,但 是釋放動態配置記憶體的問題由GC去默默收拾了。寫程式的人也許會忘記釋放 一塊記憶體,但是大部分情形下,對一塊記憶體的參考指標在離開一定的scope 後就會無效,這種事情可以由編譯器負責收拾,不需要寫程式的人刻意為之。 以前沒有GC時,一塊記憶體從heap被配置出來,heap manager多半會在它旁邊 保留幾個byte來記憶下一塊被配置記憶體或可用記憶體的位置,作為heap內部 管理用的linked list pointer,也多半會再多保留幾個byte來記錄別的內部 資訊。GC繼續延用這樣的機制,但是會要求更多空間來記錄GC機制內部使用的 資訊,所以動態配置記憶體的代價比起沒GC時要更大。 比較起來,直接使用stack的auto變數/物件,包括C#設計上刻意為之的16 bytes 大小以下的struct,都不用經過heap manager配置記憶體空間,也不必經由GC回 收記憶體,而是由編譯器在編譯時就算好該用多大的堆疊空間,直接在function/ method code被呼叫時就從堆疊中保留那樣大的空間出來用。不用花時間讓heap manager去找適當大小的可用記憶體塊來配置,也不用花時間等GC收完垃圾,所以 效能好。 ※ 引述《virdust2003 (替機殼洗個熱水澡)》之銘言: : 就我所知, heap 可以看成一塊亂糟糟的 記憶體 : 物件的東東都是存在這裡,也就是隨便挖一塊記憶體去放,所以會有很多空格 : 但是我們以前學的不都是需要一個 SP or BX (忘了是什麼了) 來取得 參數 : 但是物件需要一個指標,也就是那塊長長的記憶體位置存的都是物件的位址 : ^^^^^^^^^^^^附註 : 所以要存取物件的值的話,總共需要存取兩次記憶體。但Stack 裡面只需要32Bit就好 : 但若宣告的是 Struct 的話,例如 Point ,那麼 x,y 就是直接放在 Stack 裡面 : 存取的話,直接用暫存器加減X就可以取得了,也就是一次KO~ : 不知道這樣說的明白嗎? : PS:曾問過我的組語老師,Heap相關問題,他回說:「Heap是什麼?」 : 所以也有可能 Heap 是GC出來之後的產物 : 至於 16byte以下用 Struct效率比較好,是在TechEd 2004 聽到蔡學鏞講的~ : 物件導向的語言 其字串也是放在 Heap 中,所以每次指派才都會多出一塊垃圾記憶體~ : 但若早期的C, 程式一開始即宣告好的字串就是 Stack了~ : 動態的話,我想應該也叫做Stack ,因為那時候沒有gc可以幫你回收 ,都要自己free 掉 : 附註: : 長長的記憶體指的是 Code從上面開始,Data從下面開始,以前學組語的那種模型 : 所以Data太多還會蓋到 Code ,我覺得還滿好笑的~ --



※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 61.222.17.194 ※ 編輯: Aurim 來自: 61.222.17.194 (07/13 14:16)
1F:推 Jadecar:好文耶...很詳細,這些資訊要看什麼書才能知道啊 140.111.79.32 07/13
2F:推 Arton0306:推呀 08/10 16:55
3F:→ Arton0306:咦 原來是2005年的文XD 08/10 16:56







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:WOW站內搜尋

TOP