亚洲免费乱码视频,日韩 欧美 国产 动漫 一区,97在线观看免费视频播国产,中文字幕亚洲图片

      1. <legend id="ppnor"></legend>

      2. 
        
        <sup id="ppnor"><input id="ppnor"></input></sup>
        <s id="ppnor"></s>

        保持C/C++程序代碼的可伸縮性

        字號:

        在今天,已有許多的32位應(yīng)用程序感到,在32位平臺上可用的虛擬內(nèi)存受到了一定的限制,對程序開發(fā)者來說,即使是開始關(guān)注64位平臺時,也不得不維護(hù)軟件的32位版本,這就需要一種方法,以使代碼的兩個版本都保持相當(dāng)?shù)目缮炜s性。
            目前的內(nèi)存剖析工具能幫助確定,當(dāng)程序達(dá)到峰值內(nèi)存使用量時,都發(fā)生了什么,但是這些工具都過于關(guān)注已分配的內(nèi)存塊,而不是已提交的虛擬內(nèi)存地址空間,而這兩種衡量標(biāo)準(zhǔn)沒有直接的相關(guān)性,如內(nèi)存泄漏、內(nèi)存碎片、內(nèi)存塊內(nèi)的空間浪費(fèi)、或過度延遲的內(nèi)存單元重新分配這些因素,都會導(dǎo)致不必要的虛擬內(nèi)存提交。運(yùn)行時分析工具如IBM Rational Purify或Parasoft Inuse均可以提供內(nèi)存泄漏及已用內(nèi)存的描述,這些信息是非常有用的,但是,一個特殊的內(nèi)存塊也許可能、也許不可能影響到虛擬內(nèi)存覆蓋區(qū),另外,甚至一個有碎片的內(nèi)存堆中的一個小塊,也能直接影響到虛擬內(nèi)存覆蓋區(qū)。從另一方面來說,在此范圍內(nèi)的任意內(nèi)存塊--甚至泄漏的塊,對虛擬內(nèi)存覆蓋區(qū)來說,也不會與之有什么關(guān)系,除非每一個此范圍內(nèi)有用的內(nèi)存塊能重新分配到一個更緊湊的范圍內(nèi),這就有點(diǎn)像Java或托管程序的垃圾回收機(jī)制,但對大多數(shù)C/C++本地應(yīng)用程序來說,就絕對不可能了,因?yàn)樵谔摂M內(nèi)存空間中,它們內(nèi)存塊的位置是不確定的。
            至于本地代碼,不必要的虛擬內(nèi)存使用,這個實(shí)際的問題,比未清理的內(nèi)存塊這個理論上的問題,更加有實(shí)質(zhì)性。未清理的內(nèi)存塊可能導(dǎo)致虛擬內(nèi)存的浪費(fèi),造成過多的系統(tǒng)開銷,但或者不會;這完全依賴于堆管理器是否提交了更多的虛擬內(nèi)存,以支撐這種浪費(fèi)。某些很小的未使用的內(nèi)存塊,不會引起不必要的堆"擴(kuò)展"。與其讓你來猜哪一個或多少已浪費(fèi)的內(nèi)存塊導(dǎo)致了堆擴(kuò)展,倒不如學(xué)會怎樣判定出有意義的浪費(fèi)是什么。當(dāng)堆中包含不再使用的內(nèi)存塊時,此時通過加入對未縮減堆的檢查,就能確定出與你的程序虛擬內(nèi)存要求有很大關(guān)系的、必須進(jìn)行的內(nèi)存塊清理。
            為找出哪一個堆中的內(nèi)存塊需多留意,必須在程序中加入一些額外的代碼,以跟蹤內(nèi)存堆范圍及已分配的內(nèi)存塊。對額外的代碼進(jìn)行條件編譯,生成一個特定的版本,也許是一個不錯的辦法。
            為達(dá)到此目的,需編寫自定義的內(nèi)存分配例程,并跟蹤每一個內(nèi)存塊,另有一個自定義的釋放例程,且跟蹤虛擬內(nèi)存中堆的位置,請參見例1與例2的偽代碼算法。可能還需編寫自定義的訪問函數(shù)以標(biāo)記出訪問過的內(nèi)存塊,以便于在適當(dāng)?shù)臅r候釋放虛擬內(nèi)存,所有這些并不需要過多的內(nèi)存開銷。另一方面,如果你的程序以堆的形式使用了大量的內(nèi)存,那么將會極大地降低性能,此處的方法也不是長久之計(jì)。
            例1:
            /* 輸入?yún)?shù)*/
            ADDRESS triggerAddr
            SIZE triggerSize
            LIST a list of tracked heap ranges
            IF (the virtual memory at triggerAddr is tracked on the list as part of a heap range)
            DO
            IF (triggerAddr + triggerSize >
            (the tracked upper boundary of that heap range))
            DO
            /* 一個現(xiàn)有的堆范圍被擴(kuò)展 */
            make system call(s) to determine the base and extent of the newly committed range that contains the addresses from triggerAddr to (triggerAddr + triggerSize)
            update the size of the tracked heap range to indicate its new upper limit
            END
            END
            ELSE DO
            /* 在triggerAddr中有一個新的堆范圍 */
            make system call(s) to determine the base and extent of the newly committed range that contains the addresses from triggerAddr to (triggerAddr + triggerSize)
            track the new committed range in the list of heap ranges
            END
            例2:
            /* 輸入?yún)?shù) */
            ADDRESS triggerAddr
            SIZE triggerSize
            LIST a list of tracked heap ranges
            /* 局部變量 */
            ADDRESS origRangeBase
            SIZE origRangeSize
            BOOL bFoundChange
            bFoundChange = FALSE
            IF (the virtual memory at triggerAddr is not tracked on the heap range list as part of a heap range)
            DO
            /*似乎我們已經(jīng)清楚此次釋放了。*/
            END
            ELSE IF (an Access exception occurs when memory at triggerAddr is read)
            DO
            bFoundChange = TRUE
            END
            IF (bFoundChange) DO
            /*因?yàn)橹皟?nèi)存塊占用的空間被釋放了,所以堆占用的虛擬內(nèi)存范圍就改變了。*/
            make system calls to determine the bases and extents of the tracked committed heap ranges in the immediate vicinity of the decommitted range that includes the addresses from triggerAddr to (triggerAddr + triggerSize)
            /*更新堆范圍跟蹤,以反映剩余提交的范圍 */
            IF (any portion of the tracked heap range that contained the block at TriggerAddr is still committed)
            DO
            update the heap range list to track just the portion(s) of that range that remain committed
            END
            ELSE
            DO
            delete the list element that tracks the range
            END
            END