• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            幽幽
             
            posts - 51,  comments - 28,  trackbacks - 0
            本文轉(zhuǎn)自: http://hi.baidu.com/csuhkx/blog/item/267418d3614cf9013bf3cf55.html

            這篇文章是翻譯MSDN上一篇叫《Heap: Pleasures and Pains》的文章的

            Murali R. Krishnan
            Microsoft Corporation

            1999 年 2 月

            摘要: 討論常見(jiàn)的堆性能問(wèn)題以及如何防范它們。(共 9 頁(yè))

            前言

            您是否是動(dòng)態(tài)分配的 C/C++ 對(duì)象忠實(shí)且幸運(yùn)的用戶(hù)?您是否在模塊間的往返通信中頻繁地使用了“自動(dòng)化”?您的程序是否因堆分配而運(yùn)行起來(lái)很慢?不僅僅您遇到這樣的問(wèn)題。幾乎所有項(xiàng)目遲早都會(huì)遇到堆問(wèn)題。大家都想說(shuō),“我的代碼真正好,只是堆太慢”。那只是部分正確。更深入理解堆及其用法、以及會(huì)發(fā)生什么問(wèn)題,是很有用的。

            什么是堆?

            (如果您已經(jīng)知道什么是堆,可以跳到“什么是常見(jiàn)的堆性能問(wèn)題?”部分)

            在程序中,使用堆來(lái)動(dòng)態(tài)分配和釋放對(duì)象。在下列情況下,調(diào)用堆操作:

            1. 事先不知道程序所需對(duì)象的數(shù)量和大小。

            2. 對(duì)象太大而不適合堆棧分配程序。

            堆使用了在運(yùn)行時(shí)分配給代碼和堆棧的內(nèi)存之外的部分內(nèi)存。下圖給出了堆分配程序的不同層。

            GlobalAlloc/GlobalFree:Microsoft Win32 堆調(diào)用,這些調(diào)用直接與每個(gè)進(jìn)程的默認(rèn)堆進(jìn)行對(duì)話(huà)。

            LocalAlloc/LocalFree:Win32 堆調(diào)用(為了與 Microsoft Windows NT 兼容),這些調(diào)用直接與每個(gè)進(jìn)程的默認(rèn)堆進(jìn)行對(duì)話(huà)。

            COM 的 IMalloc 分配程序(或 CoTaskMemAlloc / CoTaskMemFree):函數(shù)使用每個(gè)進(jìn)程的默認(rèn)堆。自動(dòng)化程序使用“組件對(duì)象模型 (COM)”的分配程序,而申請(qǐng)的程序使用每個(gè)進(jìn)程堆。

            C/C++ 運(yùn)行時(shí) (CRT) 分配程序:提供了 malloc()free() 以及 newdelete 操作符。如 Microsoft Visual Basic 和 Java 等語(yǔ)言也提供了新的操作符并使用垃圾收集來(lái)代替堆。CRT 創(chuàng)建自己的私有堆,駐留在 Win32 堆的頂部。

            Windows NT 中,Win32 堆是 Windows NT 運(yùn)行時(shí)分配程序周?chē)谋印K?API 轉(zhuǎn)發(fā)它們的請(qǐng)求給 NTDLL。

            Windows NT 運(yùn)行時(shí)分配程序提供 Windows NT 內(nèi)的核心堆分配程序。它由具有 128 個(gè)大小從 8 到 1,024 字節(jié)的空閑列表的前端分配程序組成。后端分配程序使用虛擬內(nèi)存來(lái)保留和提交頁(yè)。

            在圖表的底部是“虛擬內(nèi)存分配程序”,操作系統(tǒng)使用它來(lái)保留和提交頁(yè)。所有分配程序使用虛擬內(nèi)存進(jìn)行數(shù)據(jù)的存取。

            分配和釋放塊不就那么簡(jiǎn)單嗎?為何花費(fèi)這么長(zhǎng)時(shí)間?

            堆實(shí)現(xiàn)的注意事項(xiàng)

            傳統(tǒng)上,操作系統(tǒng)和運(yùn)行時(shí)庫(kù)是與堆的實(shí)現(xiàn)共存的。在一個(gè)進(jìn)程的開(kāi)始,操作系統(tǒng)創(chuàng)建一個(gè)默認(rèn)堆,叫做“進(jìn)程堆”。如果沒(méi)有其他堆可使用,則塊的分配使用“進(jìn)程堆”。語(yǔ)言運(yùn)行時(shí)也能在進(jìn)程內(nèi)創(chuàng)建單獨(dú)的堆。(例如,C 運(yùn)行時(shí)創(chuàng)建它自己的堆。)除這些專(zhuān)用的堆外,應(yīng)用程序或許多已載入的動(dòng)態(tài)鏈接庫(kù) (DLL) 之一可以創(chuàng)建和使用單獨(dú)的堆。Win32 提供一整套 API 來(lái)創(chuàng)建和使用私有堆。有關(guān)堆函數(shù)(英文)的詳盡指導(dǎo),請(qǐng)參見(jiàn) MSDN。

            當(dāng)應(yīng)用程序或 DLL 創(chuàng)建私有堆時(shí),這些堆存在于進(jìn)程空間,并且在進(jìn)程內(nèi)是可訪(fǎng)問(wèn)的。從給定堆分配的數(shù)據(jù)將在同一個(gè)堆上釋放。(不能從一個(gè)堆分配而在另一個(gè)堆釋放。)

            在所有虛擬內(nèi)存系統(tǒng)中,堆駐留在操作系統(tǒng)的“虛擬內(nèi)存管理器”的頂部。語(yǔ)言運(yùn)行時(shí)堆也駐留在虛擬內(nèi)存頂部。某些情況下,這些堆是操作系統(tǒng)堆中的層,而語(yǔ)言運(yùn)行時(shí)堆則通過(guò)大塊的分配來(lái)執(zhí)行自己的內(nèi)存管理。不使用操作系統(tǒng)堆,而使用虛擬內(nèi)存函數(shù)更利于堆的分配和塊的使用。

            典型的堆實(shí)現(xiàn)由前、后端分配程序組成。前端分配程序維持固定大小塊的空閑列表。對(duì)于一次分配調(diào)用,堆嘗試從前端列表找到一個(gè)自由塊。如果失敗,堆被迫從后端(保留和提交虛擬內(nèi)存)分配一個(gè)大塊來(lái)滿(mǎn)足請(qǐng)求。通用的實(shí)現(xiàn)有每塊分配的開(kāi)銷(xiāo),這將耗費(fèi)執(zhí)行周期,也減少了可使用的存儲(chǔ)空間。

            Knowledge Base 文章 Q10758,“用 calloc() 和 malloc() 管理內(nèi)存” (搜索文章編號(hào)), 包含了有關(guān)這些主題的更多背景知識(shí)。另外,有關(guān)堆實(shí)現(xiàn)和設(shè)計(jì)的詳細(xì)討論也可在下列著作中找到:“Dynamic Storage Allocation: A Survey and Critical Review”,作者 Paul R. Wilson、Mark S. Johnstone、Michael Neely 和 David Boles;“International Workshop on Memory Management”, 作者 Kinross, Scotland, UK, 1995 年 9 月(http://www.cs.utexas.edu/users/oops/papers.html)(英文)。

            Windows NT 的實(shí)現(xiàn)(Windows NT 版本 4.0 和更新版本) 使用了 127 個(gè)大小從 8 到 1,024 字節(jié)的 8 字節(jié)對(duì)齊塊空閑列表和一個(gè)“大塊”列表。“大塊”列表(空閑列表[0]) 保存大于 1,024 字節(jié)的塊。空閑列表容納了用雙向鏈表鏈接在一起的對(duì)象。默認(rèn)情況下,“進(jìn)程堆”執(zhí)行收集操作。(收集是將相鄰空閑塊合并成一個(gè)大塊的操作。)收集耗費(fèi)了額外的周期,但減少了堆塊的內(nèi)部碎片。

            單一全局鎖保護(hù)堆,防止多線(xiàn)程式的使用。(請(qǐng)參見(jiàn)“Server Performance and Scalability Killers”中的第一個(gè)注意事項(xiàng), George Reilly 所著,在 “MSDN Online Web Workshop”上(站點(diǎn):http://msdn.microsoft.com/workshop/server/iis/tencom.asp(英文)。)單一全局鎖本質(zhì)上是用來(lái)保護(hù)堆數(shù)據(jù)結(jié)構(gòu),防止跨多線(xiàn)程的隨機(jī)存取。若堆操作太頻繁,單一全局鎖會(huì)對(duì)性能有不利的影響。

            什么是常見(jiàn)的堆性能問(wèn)題?

            以下是您使用堆時(shí)會(huì)遇到的最常見(jiàn)問(wèn)題:

            • 分配操作造成的速度減慢。光分配就耗費(fèi)很長(zhǎng)時(shí)間。最可能導(dǎo)致運(yùn)行速度減慢原因是空閑列表沒(méi)有塊,所以運(yùn)行時(shí)分配程序代碼會(huì)耗費(fèi)周期尋找較大的空閑塊,或從后端分配程序分配新塊。

            • 釋放操作造成的速度減慢。釋放操作耗費(fèi)較多周期,主要是啟用了收集操作。收集期間,每個(gè)釋放操作“查找”它的相鄰塊,取出它們并構(gòu)造成較大塊,然后再把此較大塊插入空閑列表。在查找期間,內(nèi)存可能會(huì)隨機(jī)碰到,從而導(dǎo)致高速緩存不能命中,性能降低。

            • 堆競(jìng)爭(zhēng)造成的速度減慢。當(dāng)兩個(gè)或多個(gè)線(xiàn)程同時(shí)訪(fǎng)問(wèn)數(shù)據(jù),而且一個(gè)線(xiàn)程繼續(xù)進(jìn)行之前必須等待另一個(gè)線(xiàn)程完成時(shí)就發(fā)生競(jìng)爭(zhēng)。競(jìng)爭(zhēng)總是導(dǎo)致麻煩;這也是目前多處理器系統(tǒng)遇到的最大問(wèn)題。當(dāng)大量使用內(nèi)存塊的應(yīng)用程序或 DLL 以多線(xiàn)程方式運(yùn)行(或運(yùn)行于多處理器系統(tǒng)上)時(shí)將導(dǎo)致速度減慢。單一鎖定的使用—常用的解決方案—意味著使用堆的所有操作是序列化的。當(dāng)?shù)却i定時(shí)序列化會(huì)引起線(xiàn)程切換上下文。可以想象交叉路口閃爍的紅燈處走走停停導(dǎo)致的速度減慢。

              競(jìng)爭(zhēng)通常會(huì)導(dǎo)致線(xiàn)程和進(jìn)程的上下文切換。上下文切換的開(kāi)銷(xiāo)是很大的,但開(kāi)銷(xiāo)更大的是數(shù)據(jù)從處理器高速緩存中丟失,以及后來(lái)線(xiàn)程復(fù)活時(shí)的數(shù)據(jù)重建。

            • 堆破壞造成的速度減慢。造成堆破壞的原因是應(yīng)用程序?qū)Χ褖K的不正確使用。通常情形包括釋放已釋放的堆塊或使用已釋放的堆塊,以及塊的越界重寫(xiě)等明顯問(wèn)題。(破壞不在本文討論范圍之內(nèi)。有關(guān)內(nèi)存重寫(xiě)和泄漏等其他細(xì)節(jié),請(qǐng)參見(jiàn) Microsoft Visual C++(R) 調(diào)試文檔 。)

            • 頻繁的分配和重分配造成的速度減慢。這是使用腳本語(yǔ)言時(shí)非常普遍的現(xiàn)象。如字符串被反復(fù)分配,隨重分配增長(zhǎng)和釋放。不要這樣做,如果可能,盡量分配大字符串和使用緩沖區(qū)。另一種方法就是盡量少用連接操作。

            競(jìng)爭(zhēng)是在分配和釋放操作中導(dǎo)致速度減慢的問(wèn)題。理想情況下,希望使用沒(méi)有競(jìng)爭(zhēng)和快速分配/釋放的堆。可惜,現(xiàn)在還沒(méi)有這樣的通用堆,也許將來(lái)會(huì)有。

            在所有的服務(wù)器系統(tǒng)中(如 IIS、MSProxy、DatabaseStacks、網(wǎng)絡(luò)服務(wù)器、 Exchange 和其他), 堆鎖定實(shí)在是個(gè)大瓶頸。處理器數(shù)越多,競(jìng)爭(zhēng)就越會(huì)惡化。

            盡量減少堆的使用

            現(xiàn)在您明白使用堆時(shí)存在的問(wèn)題了,難道您不想擁有能解決這些問(wèn)題的超級(jí)魔棒嗎?我可希望有。但沒(méi)有魔法能使堆運(yùn)行加快—因此不要期望在產(chǎn)品出貨之前的最后一星期能夠大為改觀。如果提前規(guī)劃堆策略,情況將會(huì)大大好轉(zhuǎn)。調(diào)整使用堆的方法,減少對(duì)堆的操作是提高性能的良方。

            如何減少使用堆操作?通過(guò)利用數(shù)據(jù)結(jié)構(gòu)內(nèi)的位置可減少堆操作的次數(shù)。請(qǐng)考慮下列實(shí)例:

            struct ObjectA {
                // objectA 的數(shù)據(jù)
            }
            struct ObjectB {
                // objectB 的數(shù)據(jù)
            }
            // 同時(shí)使用 objectA 和 objectB
            //
            // 使用指針
            //
            struct ObjectB {
                struct ObjectA * pObjA;
                // objectB 的數(shù)據(jù)
            }
            //
            // 使用嵌入
            //
            struct ObjectB {
                struct ObjectA pObjA;
                // objectB 的數(shù)據(jù)
            }
            //
            // 集合 – 在另一對(duì)象內(nèi)使用 objectA 和 objectB
            //
            struct ObjectX {
                struct ObjectA   objA;
                struct ObjectB   objB;
            }
            
            1. 避免使用指針關(guān)聯(lián)兩個(gè)數(shù)據(jù)結(jié)構(gòu)。如果使用指針關(guān)聯(lián)兩個(gè)數(shù)據(jù)結(jié)構(gòu),前面實(shí)例中的對(duì)象 A 和 B 將被分別分配和釋放。這會(huì)增加額外開(kāi)銷(xiāo)—我們要避免這種做法。

            2. 把帶指針的子對(duì)象嵌入父對(duì)象。當(dāng)對(duì)象中有指針時(shí),則意味著對(duì)象中有動(dòng)態(tài)元素(百分之八十)和沒(méi)有引用的新位置。嵌入增加了位置從而減少了進(jìn)一步分配/釋放的需求。這將提高應(yīng)用程序的性能。

            3. 合并小對(duì)象形成大對(duì)象(聚合)。聚合減少分配和釋放的塊的數(shù)量。如果有幾個(gè)開(kāi)發(fā)者,各自開(kāi)發(fā)設(shè)計(jì)的不同部分,則最終會(huì)有許多小對(duì)象需要合并。集成的挑戰(zhàn)就是要找到正確的聚合邊界。

            4. 內(nèi)聯(lián)緩沖區(qū)能夠滿(mǎn)足百分之八十的需要(aka 80-20 規(guī)則)。個(gè)別情況下,需要內(nèi)存緩沖區(qū)來(lái)保存字符串/二進(jìn)制數(shù)據(jù),但事先不知道總字節(jié)數(shù)。估計(jì)并內(nèi)聯(lián)一個(gè)大小能滿(mǎn)足百分之八十需要的緩沖區(qū)。對(duì)剩余的百分之二十,可以分配一個(gè)新的緩沖區(qū)和指向這個(gè)緩沖區(qū)的指針。這樣,就減少分配和釋放調(diào)用并增加數(shù)據(jù)的位置空間,從根本上提高代碼的性能。

            5. 在塊中分配對(duì)象(塊化)。塊化是以組的方式一次分配多個(gè)對(duì)象的方法。如果對(duì)列表的項(xiàng)連續(xù)跟蹤,例如對(duì)一個(gè) {名稱(chēng),值} 對(duì)的列表,有兩種選擇:選擇一是為每一個(gè)“名稱(chēng)-值”對(duì)分配一個(gè)節(jié)點(diǎn);選擇二是分配一個(gè)能容納(如五個(gè))“名稱(chēng)-值”對(duì)的結(jié)構(gòu)。例如,一般情況下,如果存儲(chǔ)四對(duì),就可減少節(jié)點(diǎn)的數(shù)量,如果需要額外的空間數(shù)量,則使用附加的鏈表指針。

              塊化是友好的處理器高速緩存,特別是對(duì)于 L1-高速緩存,因?yàn)樗峁┝嗽黾拥奈恢?—不用說(shuō)對(duì)于塊分配,很多數(shù)據(jù)塊會(huì)在同一個(gè)虛擬頁(yè)中。

            6. 正確使用 _amblksiz。C 運(yùn)行時(shí) (CRT) 有它的自定義前端分配程序,該分配程序從后端(Win32 堆)分配大小為 _amblksiz 的塊。將 _amblksiz 設(shè)置為較高的值能潛在地減少對(duì)后端的調(diào)用次數(shù)。這只對(duì)廣泛使用 CRT 的程序適用。

            使用上述技術(shù)將獲得的好處會(huì)因?qū)ο箢?lèi)型、大小及工作量而有所不同。但總能在性能和可升縮性方面有所收獲。另一方面,代碼會(huì)有點(diǎn)特殊,但如果經(jīng)過(guò)深思熟慮,代碼還是很容易管理的。

            其他提高性能的技術(shù)

            下面是一些提高速度的技術(shù):

            1. 使用 Windows NT5 堆

              由于幾個(gè)同事的努力和辛勤工作,1998 年初 Microsoft Windows(R) 2000 中有了幾個(gè)重大改進(jìn):

              • 改進(jìn)了堆代碼內(nèi)的鎖定。堆代碼對(duì)每堆一個(gè)鎖。全局鎖保護(hù)堆數(shù)據(jù)結(jié)構(gòu),防止多線(xiàn)程式的使用。但不幸的是,在高通信量的情況下,堆仍受困于全局鎖,導(dǎo)致高競(jìng)爭(zhēng)和低性能。Windows 2000 中,鎖內(nèi)代碼的臨界區(qū)將競(jìng)爭(zhēng)的可能性減到最小,從而提高了可伸縮性。

              • 使用 “Lookaside”列表。堆數(shù)據(jù)結(jié)構(gòu)對(duì)塊的所有空閑項(xiàng)使用了大小在 8 到 1,024 字節(jié)(以 8-字節(jié)遞增)的快速高速緩存。快速高速緩存最初保護(hù)在全局鎖內(nèi)。現(xiàn)在,使用 lookaside 列表來(lái)訪(fǎng)問(wèn)這些快速高速緩存空閑列表。這些列表不要求鎖定,而是使用 64 位的互鎖操作,因此提高了性能。

              • 內(nèi)部數(shù)據(jù)結(jié)構(gòu)算法也得到改進(jìn)。

              這些改進(jìn)避免了對(duì)分配高速緩存的需求,但不排除其他的優(yōu)化。使用 Windows NT5 堆評(píng)估您的代碼;它對(duì)小于 1,024 字節(jié) (1 KB) 的塊(來(lái)自前端分配程序的塊)是最佳的。GlobalAlloc()LocalAlloc() 建立在同一堆上,是存取每個(gè)進(jìn)程堆的通用機(jī)制。如果希望獲得高的局部性能,則使用 Heap(R) API 來(lái)存取每個(gè)進(jìn)程堆,或?yàn)榉峙洳僮鲃?chuàng)建自己的堆。如果需要對(duì)大塊操作,也可以直接使用 VirtualAlloc() / VirtualFree() 操作。

              上述改進(jìn)已在 Windows 2000 beta 2 和 Windows NT 4.0 SP4 中使用。改進(jìn)后,堆鎖的競(jìng)爭(zhēng)率顯著降低。這使所有 Win32 堆的直接用戶(hù)受益。CRT 堆建立于 Win32 堆的頂部,但它使用自己的小塊堆,因而不能從 Windows NT 改進(jìn)中受益。(Visual C++ 版本 6.0 也有改進(jìn)的堆分配程序。)

            2. 使用分配高速緩存

              分配高速緩存允許高速緩存分配的塊,以便將來(lái)重用。這能夠減少對(duì)進(jìn)程堆(或全局堆)的分配/釋放調(diào)用的次數(shù),也允許最大限度的重用曾經(jīng)分配的塊。另外,分配高速緩存允許收集統(tǒng)計(jì)信息,以便較好地理解對(duì)象在較高層次上的使用。

              典型地,自定義堆分配程序在進(jìn)程堆的頂部實(shí)現(xiàn)。自定義堆分配程序與系統(tǒng)堆的行為很相似。主要的差別是它在進(jìn)程堆的頂部為分配的對(duì)象提供高速緩存。高速緩存設(shè)計(jì)成一套固定大小(如 32 字節(jié)、64 字節(jié)、128 字節(jié)等)。這一個(gè)很好的策略,但這種自定義堆分配程序丟失與分配和釋放的對(duì)象相關(guān)的“語(yǔ)義信息”。

              與自定義堆分配程序相反,“分配高速緩存”作為每類(lèi)分配高速緩存來(lái)實(shí)現(xiàn)。除能夠提供自定義堆分配程序的所有好處之外,它們還能夠保留大量語(yǔ)義信息。每個(gè)分配高速緩存處理程序與一個(gè)目標(biāo)二進(jìn)制對(duì)象關(guān)聯(lián)。它能夠使用一套參數(shù)進(jìn)行初始化,這些參數(shù)表示并發(fā)級(jí)別、對(duì)象大小和保持在空閑列表中的元素的數(shù)量等。分配高速緩存處理程序?qū)ο缶S持自己的私有空閑實(shí)體池(不超過(guò)指定的閥值)并使用私有保護(hù)鎖。合在一起,分配高速緩存和私有鎖減少了與主系統(tǒng)堆的通信量,因而提供了增加的并發(fā)、最大限度的重用和較高的可伸縮性。

              需要使用清理程序來(lái)定期檢查所有分配高速緩存處理程序的活動(dòng)情況并回收未用的資源。如果發(fā)現(xiàn)沒(méi)有活動(dòng),將釋放分配對(duì)象的池,從而提高性能。

              可以審核每個(gè)分配/釋放活動(dòng)。第一級(jí)信息包括對(duì)象、分配和釋放調(diào)用的總數(shù)。通過(guò)查看它們的統(tǒng)計(jì)信息可以得出各個(gè)對(duì)象之間的語(yǔ)義關(guān)系。利用以上介紹的許多技術(shù)之一,這種關(guān)系可以用來(lái)減少內(nèi)存分配。

              分配高速緩存也起到了調(diào)試助手的作用,幫助您跟蹤沒(méi)有完全清除的對(duì)象數(shù)量。通過(guò)查看動(dòng)態(tài)堆棧返回蹤跡和除沒(méi)有清除的對(duì)象之外的簽名,甚至能夠找到確切的失敗的調(diào)用者。

            3. MP 堆

              MP 堆是對(duì)多處理器友好的分布式分配的程序包,在 Win32 SDK(Windows NT 4.0 和更新版本)中可以得到。最初由 JVert 實(shí)現(xiàn),此處堆抽象建立在 Win32 堆程序包的頂部。MP 堆創(chuàng)建多個(gè) Win32 堆,并試圖將分配調(diào)用分布到不同堆,以減少在所有單一鎖上的競(jìng)爭(zhēng)。

              本程序包是好的步驟 —一種改進(jìn)的 MP-友好的自定義堆分配程序。但是,它不提供語(yǔ)義信息和缺乏統(tǒng)計(jì)功能。通常將 MP 堆作為 SDK 庫(kù)來(lái)使用。如果使用這個(gè) SDK 創(chuàng)建可重用組件,您將大大受益。但是,如果在每個(gè) DLL 中建立這個(gè) SDK 庫(kù),將增加工作設(shè)置。

            4. 重新思考算法和數(shù)據(jù)結(jié)構(gòu)

              要在多處理器機(jī)器上伸縮,則算法、實(shí)現(xiàn)、數(shù)據(jù)結(jié)構(gòu)和硬件必須動(dòng)態(tài)伸縮。請(qǐng)看最經(jīng)常分配和釋放的數(shù)據(jù)結(jié)構(gòu)。試問(wèn),“我能用不同的數(shù)據(jù)結(jié)構(gòu)完成此工作嗎?”例如,如果在應(yīng)用程序初始化時(shí)加載了只讀項(xiàng)的列表,這個(gè)列表不必是線(xiàn)性鏈接的列表。如果是動(dòng)態(tài)分配的數(shù)組就非常好。動(dòng)態(tài)分配的數(shù)組將減少內(nèi)存中的堆塊和碎片,從而增強(qiáng)性能。

              減少需要的小對(duì)象的數(shù)量減少堆分配程序的負(fù)載。例如,我們?cè)诜?wù)器的關(guān)鍵處理路徑上使用五個(gè)不同的對(duì)象,每個(gè)對(duì)象單獨(dú)分配和釋放。一起高速緩存這些對(duì)象,把堆調(diào)用從五個(gè)減少到一個(gè),顯著減少了堆的負(fù)載,特別當(dāng)每秒鐘處理 1,000 個(gè)以上的請(qǐng)求時(shí)。

              如果大量使用“Automation”結(jié)構(gòu),請(qǐng)考慮從主線(xiàn)代碼中刪除“Automation BSTR”,或至少避免重復(fù)的 BSTR 操作。(BSTR 連接導(dǎo)致過(guò)多的重分配和分配/釋放操作。)

            摘要

            對(duì)所有平臺(tái)往往都存在堆實(shí)現(xiàn),因此有巨大的開(kāi)銷(xiāo)。每個(gè)單獨(dú)代碼都有特定的要求,但設(shè)計(jì)能采用本文討論的基本理論來(lái)減少堆之間的相互作用。

            1. 評(píng)價(jià)您的代碼中堆的使用。

            2. 改進(jìn)您的代碼,以使用較少的堆調(diào)用:分析關(guān)鍵路徑和固定數(shù)據(jù)結(jié)構(gòu)。

            3. 在實(shí)現(xiàn)自定義的包裝程序之前使用量化堆調(diào)用成本的方法。

            4. 如果對(duì)性能不滿(mǎn)意,請(qǐng)要求 OS 組改進(jìn)堆。更多這類(lèi)請(qǐng)求意味著對(duì)改進(jìn)堆的更多關(guān)注。

            5. 要求 C 運(yùn)行時(shí)組針對(duì) OS 所提供的堆制作小巧的分配包裝程序。隨著 OS 堆的改進(jìn),C 運(yùn)行時(shí)堆調(diào)用的成本將減小。

            6. 操作系統(tǒng)(Windows NT 家族)正在不斷改進(jìn)堆。請(qǐng)隨時(shí)關(guān)注和利用這些改進(jìn)。

            Murali Krishnan 是 Internet Information Server (IIS) 組的首席軟件設(shè)計(jì)工程師。從 1.0 版本開(kāi)始他就設(shè)計(jì) IIS,并成功發(fā)行了 1.0 版本到 4.0 版本。Murali 組織并領(lǐng)導(dǎo) IIS 性能組三年 (1995-1998), 從一開(kāi)始就影響 IIS 性能。他擁有威斯康星州 Madison 大學(xué)的 M.S.和印度 Anna 大學(xué)的 B.S.。工作之外,他喜歡閱讀、打排球和家庭烹飪。


            posted on 2009-02-03 08:49 幽幽 閱讀(495) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): Windows

            <2008年7月>
            293012345
            6789101112
            13141516171819
            20212223242526
            272829303112
            3456789

            常用鏈接

            留言簿(6)

            隨筆分類(lèi)(35)

            隨筆檔案(51)

            文章分類(lèi)(3)

            文章檔案(3)

            相冊(cè)

            我的鏈接

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            久久精品亚洲乱码伦伦中文| 久久精品国产亚洲av麻豆图片 | 亚洲国产成人精品无码久久久久久综合| 国产精品久久久久9999| 欧美久久久久久精选9999| 亚洲国产精品久久久天堂| 国内精品久久久久久中文字幕| 少妇久久久久久被弄到高潮| 国产日产久久高清欧美一区| 久久久无码精品亚洲日韩京东传媒| 久久亚洲综合色一区二区三区| 久久乐国产综合亚洲精品| 国产成人精品久久亚洲| 精品久久久久久成人AV| 久久久精品人妻一区二区三区蜜桃| 久久精品国产亚洲麻豆| 久久久久久久97| 亚洲AV无码久久精品蜜桃| 一本一道久久a久久精品综合| 91精品国产综合久久四虎久久无码一级| 伊人久久大香线焦AV综合影院| 久久久黄片| 很黄很污的网站久久mimi色| 久久精品国产精品国产精品污| 人妻无码αv中文字幕久久琪琪布 人妻无码久久一区二区三区免费 人妻无码中文久久久久专区 | 曰曰摸天天摸人人看久久久| 久久精品国产亚洲AV高清热 | 亚洲AV无码久久精品色欲| 久久无码AV中文出轨人妻| 久久婷婷五月综合97色直播| 国产99久久久国产精品~~牛| 国产精品久久永久免费| 久久ZYZ资源站无码中文动漫| 色8久久人人97超碰香蕉987| 久久久久久综合网天天| 亚洲日本va中文字幕久久| 久久综合给久久狠狠97色| 久久男人Av资源网站无码软件| 久久久久亚洲AV无码麻豆| 久久久久亚洲精品天堂| 狠狠色婷婷综合天天久久丁香 |