Re: [問題] stack v.s. heap sizes

看板C_and_CPP (C/C++)作者 (眾生都是未來佛)時間15年前 (2010/08/31 08:38), 編輯推噓1(1051)
留言52則, 4人參與, 最新討論串3/3 (看更多)
[恕刪] 先謝謝t大,我許多疑惑都比較清楚了。 但還有些疑惑。 : → tinlans:process 是在 virtual address space 上工作的,所以當然 08/30 22:07 : → tinlans:不會在你沒使用到的時候就去佔到實體記憶體。 08/30 22:08 : → tinlans:但是這完全依賴 OS 的實作,如果很不幸的你偏偏就只用到那 08/30 22:09 : → tinlans:麼大的空間一次而已,實體空間就這樣被你佔下來。後續其它 08/30 22:09 : → tinlans:process 也要佔用實體記憶體時,swap out 就會拖慢速度。 08/30 22:10 這是指physical mem(ory)不足,所以要用hard disk space作swap sapce, 所以變慢嗎? 但如果dynamic variable過大,也應該會造成一樣問題吧。 不過dynamic variable這時還是有個好處, 就是它能在programmer在想釋放的時間點就釋放。 automatic variable只能等到function scope結束才釋放,缺乏彈性, (這hard disk space作成的swap space就是我上面所說的virtual mem。 Windows真的叫它virtual mem (Windows 7/Start Menu/Computer/Properties/Advanced System Settings/ Performace Settings/Advanced tab/Virtual Memory), 它跟計概所說的virtual mem是兩回事XD 為作區別,不如叫後者process virtual mem!?) : → tinlans:如果是在沒有虛擬記憶體的 real-time system,這樣搞就會 08/30 22:11 : → tinlans:直接往實體記憶體吃下去了。 08/30 22:11 : → tinlans:但是最大的問題還是在於,32-bit 系統上定址空間有限。 08/30 22:12 64-bit system可能就不是問題了XD 其實我已試過在Windows Server 2008 R2 64-bit下試圖叫出更大stack size, 但似乎是目前Visual C++ 2010 64-bit compiler支援度不好, 太大的automatic variables就發生compiler internal error XD : → tinlans:你如果是 user/kernel = 2G/2G 的 model,stack 一吃就把 08/30 22:12 : → tinlans:user space 的 90% 吃光光,你 heap 的可用空間就會受限。 08/30 22:12 : → tinlans:另一個問題就在於你無法開 thread,因為開 thread 會由 OS 08/30 22:13 : → tinlans:配置第二個 stack 出來給新的 thread 用。 08/30 22:13 問個問題,這新開的thread的stack size大小如何決定? : → tinlans:如果你想讓 stack 變成跟 heap 一樣會動態增長, 08/30 22:17 : → tinlans:不是一開始就 allocate 好,那就得在每個 function call 08/30 22:18 : → tinlans:跟 return 的位置做一些 stack size 的檢查,然後決定 08/30 22:18 : → tinlans:是不是要跟 OS 要更多 stack 的空間,程式會又慢又肥。 08/30 22:19 總之,在少次配置的大variables時建議用heap。 雖然我們不見得會遇上一些stack有弱點的地方如 real-time system、embedded system(我不確定!?)、multithreading programming, 但這種coding style,是可以避開未來會遇上這些問題, 除非真的很care速度(如dynamic variable的access需要多用個指標操作)。 至於其他不大的variables,就建議用stack。 : 推 VictorTom:推t大的說明:) 08/30 23:14 : 推 loveme00835:推 t 大熱心, 好久沒看到 v 大 XD 08/30 23:29 : 推 nowar100:我覺得這篇推文很有價值 等下看怎樣收進精華區 08/30 23:30 : → nowar100:放這 z-10-13 08/30 23:34 : 推 VictorTom:小弟我現在公司不能上PTT, 只能回家抽空看Q_Q~ 08/31 01:01 -- 信佛的人要知道:佛絕不會說謊。但請把握時光。 法滅盡經: http://www.cbeta.org/result/normal/T12/0396_001.htm 共勉之。 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.115.221.79 ※ 編輯: zxvc 來自: 140.115.221.79 (08/31 08:40)

08/31 14:07, , 1F
所以說要看 OS 實作。有些是你 allocate 完在第一次
08/31 14:07, 1F

08/31 14:07, , 2F
reference 到才會真的佔到實體記憶體;有些可能會用預測或
08/31 14:07, 2F

08/31 14:09, , 3F
預先佔用的方式把它佔下來。去假設被 allocate 走的區間何
08/31 14:09, 3F

08/31 14:09, , 4F
時真正佔用記憶體,就多了很多不確定性。
08/31 14:09, 4F

08/31 14:10, , 5F
另外 C++ 的多型只作用在 pointer 和 reference 上,
08/31 14:10, 5F

08/31 14:11, , 6F
雖然可以用一些 syntax 技巧讓 stack 物件具多型性,
08/31 14:11, 6F

08/31 14:11, , 7F
但是那會造成 programmer 不知道到底要不要 delete 的困擾
08/31 14:11, 7F

08/31 14:11, , 8F
,所以很多時候還是直接把它 new 在 heap 上面。
08/31 14:11, 8F

08/31 14:13, , 9F
pthread 的話 stack size 可用 pthread_attr_getstacksize
08/31 14:13, 9F

08/31 14:13, , 10F
這個函式得到,當然它也有對應的 set 函式。
08/31 14:13, 10F

08/31 14:14, , 11F
每個平台的不同 thread model 都有不同的決定策略,
08/31 14:14, 11F

08/31 14:14, , 12F
甚至有些會直接看你的執行檔 header 就能決定也不意外。
08/31 14:14, 12F

08/31 14:15, , 13F
當然這邊講的並不是指 main thread 的 stack size。
08/31 14:15, 13F

08/31 15:23, , 14F
謝謝t大,雖然多型那一段我還不是很了解。
08/31 15:23, 14F

08/31 17:48, , 15F
t 大說的是這個 http://codepad.org/ltXzyfvX 不過就
08/31 17:48, 15F

08/31 17:48, , 16F
像程式碼所呈現的, 用的語法可能會讓你忘記物件的解構
08/31 17:48, 16F

08/31 17:49, , 17F
該由誰負責, 所以 heap based object 還是用指標存取
08/31 17:49, 17F

08/31 17:49, , 18F
會比較好
08/31 17:49, 18F

09/01 01:23, , 19F
看了範例 才發現我的virtual function 學的不太好 XD
09/01 01:23, 19F

09/01 08:10, , 20F
謝謝l大,我懂了。其實這是coding style的問題,的確大多數見
09/01 08:10, 20F

09/01 08:11, , 21F
到的多型作法都是用指標或參考去指heap objects,然後再
09/01 08:11, 21F

09/01 08:12, , 22F
delete。指stack object不是不行,只是這種coding style可能
09/01 08:12, 22F

09/01 08:13, , 23F
會與別人格格不入,可能別人在用你的code的時候就很順手的來
09/01 08:13, 23F

09/01 08:15, , 24F
個delete,會造成困擾。
09/01 08:15, 24F

09/01 08:27, , 25F
不過後來想想,如果遵守"誰配置什麼object,就誰要知道如何
09/01 08:27, 25F

09/01 08:28, , 26F
釋放"這規則,上述的誤delete問題似乎也不太會發生。
09/01 08:28, 26F

09/01 08:30, , 27F
比如說,一個多型函式不該delete某個傳進來,而不是這函式
09/01 08:30, 27F

09/01 08:30, , 28F
自己配置的object,如此就不會有誤delete的問題。
09/01 08:30, 28F

09/01 08:32, , 29F
所以如果有人丟個stack object給那個函式,那人應該知道如何
09/01 08:32, 29F

09/01 08:32, , 30F
釋放這object。
09/01 08:32, 30F

09/01 08:34, , 31F
如果遵守這規則的函式,它們是更一般化的,因為它們不但可以
09/01 08:34, 31F

09/01 08:34, , 32F
處理heap object,也可以處理stack object。
09/01 08:34, 32F

09/01 14:04, , 33F
如果用factory method會把你說的情況給複雜化喔! 的確
09/01 14:04, 33F

09/01 14:06, , 34F
是coding style的問題, 傳址通常意味著物件擁有權轉移
09/01 14:06, 34F

09/01 14:07, , 35F
不給修改則是傳reference to const, pointer to const
09/01 14:07, 35F

09/01 14:08, , 36F
跟reference to non-const 雖然在callee還蠻清楚的,
09/01 14:08, 36F

09/01 14:09, , 37F
但是在 caller 端就會變得亂七八糟, 所以雖然遵循你說
09/01 14:09, 37F

09/01 14:11, , 38F
的規則是好的習慣, 但在 coding style 下功夫成效會較
09/01 14:11, 38F

09/01 14:12, , 39F
大, 可以參考「C++ Coding Styles-100 rules」一書
09/01 14:12, 39F

09/01 14:15, , 40F
^Standards
09/01 14:15, 40F

09/01 15:34, , 41F
抱歉,我不是專研CS,我發現討論的東西我愈來愈不懂了(如
09/01 15:34, 41F

09/01 15:37, , 42F
factory method)。不平衡的討論,如t、l大懂比我多,會讓
09/01 15:37, 42F

09/01 15:39, , 43F
(t、l大)失去耐心。而且CS也非我本行,現在沒什麼時間去研究
09/01 15:39, 43F

09/01 15:43, , 44F
其實z大你懂得比我多啦 ! > <
09/01 15:43, 44F

09/01 15:58, , 45F
雖然我個人還不確定t、l大有些觀點是對還是錯的,但我認為
09/01 15:58, 45F

09/01 15:59, , 46F
我且戰且走的討論模式不值得繼續下去。
09/01 15:59, 46F

09/01 16:34, , 47F
factory method 專研 CS 的教授也不見得知道。
09/01 16:34, 47F

09/01 16:34, , 48F
對 OO 的設計有興趣的話再去自修就行了。
09/01 16:34, 48F

09/01 16:36, , 49F
當然就現在是 2010 年而不是 1990 年的時間點來說,
09/01 16:36, 49F

09/01 16:36, , 50F
我個人的建議是最好把它當成程設常識學起來。
09/01 16:36, 50F

09/01 16:37, , 51F
GoF 其實也是 90 年代的產物,十幾年歷史也夠久夠穩定了。
09/01 16:37, 51F

09/01 16:57, , 52F
t 大把他們說的跟產品一樣 XD
09/01 16:57, 52F
文章代碼(AID): #1CV4yF_h (C_and_CPP)
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 3 之 3 篇):
文章代碼(AID): #1CV4yF_h (C_and_CPP)