![丨內(nèi)存使用篇如何高效來優(yōu)化軟件性能_第1頁](http://file4.renrendoc.com/view/3615fa062cb9e9a2e7426e0b61afef2f/3615fa062cb9e9a2e7426e0b61afef2f1.gif)
![丨內(nèi)存使用篇如何高效來優(yōu)化軟件性能_第2頁](http://file4.renrendoc.com/view/3615fa062cb9e9a2e7426e0b61afef2f/3615fa062cb9e9a2e7426e0b61afef2f2.gif)
![丨內(nèi)存使用篇如何高效來優(yōu)化軟件性能_第3頁](http://file4.renrendoc.com/view/3615fa062cb9e9a2e7426e0b61afef2f/3615fa062cb9e9a2e7426e0b61afef2f3.gif)
![丨內(nèi)存使用篇如何高效來優(yōu)化軟件性能_第4頁](http://file4.renrendoc.com/view/3615fa062cb9e9a2e7426e0b61afef2f/3615fa062cb9e9a2e7426e0b61afef2f4.gif)
![丨內(nèi)存使用篇如何高效來優(yōu)化軟件性能_第5頁](http://file4.renrendoc.com/view/3615fa062cb9e9a2e7426e0b61afef2f/3615fa062cb9e9a2e7426e0b61afef2f5.gif)
版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
到了時候們才使用的重,但與內(nèi)關的實不過在開始之前,我要先說明一點,就是不同編程語言的語法、解析運行機制的差異都很群都很廣泛的JaaC/C++好了,接下來,我們就一起看看如何通過代碼實現(xiàn)來優(yōu)化內(nèi)存的空間與首先你要清楚的是,通過編碼實現(xiàn)減少對內(nèi)存空間的使用,不僅能幫助你節(jié)省件運那么這樣問題也就來了:我們要如何通過編碼實現(xiàn),來減少使用的內(nèi)存下面我就詳細給你介紹下按照變量信息量選擇對應的類型定這個例子針對的是一個學生的數(shù)據(jù)信息,你可以先想,一個在校學生的有效范圍會是多少呢?首先,基于判斷,你可以認為該學生是小于0對這個場景,你在Jaa中使用一個byte可是,如果你使用ng據(jù)信息量來選擇類型定義的反例。遺憾的是,很多開發(fā)工程師在實際的代碼開發(fā)過程中,并沒有關注到這樣的代碼實現(xiàn)細節(jié)。OK,現(xiàn)在我們換個思路,看看還有沒有更極致的優(yōu)化內(nèi)存空間首先問你的是,在計算機上最小的單位是多大呢?答案是一個bit位。那么這里,我們就來看下,在C/C++中是如何記錄該學生的結構體定義的,如下所示:代代struct{unsignedchargender:unsignedchargradeId:3;//年級號unsignedchar :5;//班級號6可以看到,在這個代碼結構體中,使用了一個字節(jié)表示該學生的(gender)、年級 )。因為小學一共只有6個年級,所以年級號(gradeId)使用3個bit位保存就足夠了,其他字段也是相同原理。這樣一來,因為在C/C++位域操作(即可以針對bit位來記錄變量信息),們就可以進一步縮減內(nèi)存空間。而利用bit化之一,但比較遺憾的是,Java語言并不提供原生位域能力,因此直接使用bit但是,Java有BitSet這個類型,它可以支持位操作,不過它的主要思想是通過壓縮存比如,假設你要保存元素值為64以內(nèi)且不重復的數(shù)組:[1,3,5,6,10,11,12,25,44,56,2,55],那么如果你使用正常byte數(shù)組來保存的話,可能需要十幾個字節(jié)才可以。而使用BitSet,使用每一bit位來表示一個數(shù)字,那么用8個字節(jié)就可以記錄很多個數(shù)字了(當然,Java使用BitSet壓縮的應用場景也并不只限于這種方不過這樣問題也就來了:C/C++言的位域優(yōu)化實現(xiàn),Java否也可以實現(xiàn)這樣類其實當然是可以的,但你可能需要借助位運算。這里我們來看Java碼示例,同樣是實現(xiàn)類在一個字節(jié)保存cla,gradeID,gender等多個信息的能力,從中我們會觀察到,在Java內(nèi)也可以使用一個字節(jié),來保存多個有效的字段信息。代1publicclassStudent23bytedata;// (4bit)45Student()6data=7}89publicvoidsetGender(booleanisMale)data=(byte)(isMale?(data|0x01)(data&}publicbooleanisMale()return(data&0x01)==(byte)1?:}publicbytegetGradeId()return(byte)((data&0x0E)>>}publicvoidsetGradeId(bytegradeID)data=(byte)(data|((gradeID&<<}publicbyte ()return(byte)((data&0xF0)>>}publicvoid (byte )data=(byte)(data| &<<}33當然,上面這種實現(xiàn)可以在一些性能場景下(比大規(guī)模實例對象的場景)使用,但我并不建議你經(jīng)常使用,因為它會導致代碼的實現(xiàn)復雜度提升。實際上,針對Java而言,在絕大部分的應用場景下,選擇合適的變量類型就已經(jīng)能很大程度上減少內(nèi)存空間的浪費了。對齊對象實例內(nèi)的變量好,我們再來了解下第二個:對象實例內(nèi)變量空間對齊所以這里,我們來看下這個代碼片段,這是C/C++結構體定義(這是不考慮bit代代123456struct{unsignedcharflag;unsignedintcla;unsignedshort其中,cla的字段類型int長度為4個字節(jié),所以如果起始地址沒有4個字節(jié)對齊,那么程序在cla時,就會將其拆分在兩個指令周期內(nèi)完成,這樣勢必運行效率就很低因此,為了提升操作的性能,我們只能使用空間換時間的策略。在C/C++編譯的過程中,一般會使用字節(jié)填充技術,在char類型后面填充3個無效字節(jié),從而保證cla的起始地址是4個字節(jié)對齊的,這樣即可實現(xiàn)高效(當然你也可以通過編譯器指令顯但很明顯,這樣會帶來一個副作用,就是空間浪費而決這個題的,就是調(diào)整字段順序來實現(xiàn)字節(jié)對齊。比如說,你可以把agradleID123456struct{unsignedint;unsignedshortunsignedchar這樣一來,我們就可以在滿足字節(jié)對齊的場景下,最大化地節(jié)省內(nèi)存空比較幸運的是,JVM在優(yōu)化的過,使用了字段重排優(yōu)化技術相同類型的字段放在一起,來減少一些補白操作。所以在通常情況下,你只需要根據(jù)變量選擇合適的字段類型即可。盡量使用棧上的OK,現(xiàn)在我們來學習下第三個:盡量使用棧上內(nèi)存棧內(nèi)存就是程序調(diào)用棧上使用的內(nèi)存空間,當調(diào)用棧退出之后就可以被自動回收重復利用C/C++這里需要說明的是,如果盡量將變量定義在函數(shù)內(nèi),其實會對性能更加有利因為在Java中,如果將變量定義在類對象中,當申請內(nèi)存之后,由于內(nèi)存回收需要依賴GC實現(xiàn),因此可能在很長一段時間內(nèi),這塊內(nèi)存都不能再被回收利用了。另外,雖然在JVM優(yōu)化中,會有些棧上分配的優(yōu)化機制,但它們需要滿足很多條件才可以實現(xiàn),所OK,都是基于縮減內(nèi)存空間來實現(xiàn)優(yōu)化性能的效果,不過僅通過這個方式來提升內(nèi)存效率還是對Java語言而言,針對一個對象的new操作是非常耗時的操作,不僅需要動態(tài)在堆空間上分配內(nèi)存并進行初始化,而且在使用結束之后,還需要基于GC來管理釋放流程。那么針對內(nèi)存的申請和釋放過程,我們可以通過編碼實現(xiàn)來優(yōu)化它的性答案當然是可以的,這里常規(guī)的優(yōu)化思路主要有三點,下面我就給你詳細介紹調(diào)整內(nèi)存申請釋放發(fā)生的時首先是調(diào)整內(nèi)存申請釋放發(fā)生的時間點。這個優(yōu)化思路的出發(fā)點是:這里我們同樣來看一個代碼片段,這是一個單例模式代代123456789publicclassSingletonprivatestaticfinalSingletoninstance=newSingleton();privateSingleton(){}publicstaticSingleton{return}}從中我們可以觀察到,程序在類初始化的過會自動去創(chuàng)建對象實例,這樣就可實現(xiàn)JVM的GC回收,所以在一定程度上減少了GC是把內(nèi)存申請操作提前到啟動運行階段,從而減少運行期的動態(tài)申請開銷(模式的內(nèi)容,你可以回顧第、1講)。減少內(nèi)存的申請與釋放我們知道,在Java言中,一共包8基本類型,分別是byte、short、int、那么首先,在業(yè)務允許的情況下,我們會優(yōu)先使用基本類型,避免使用包裝類型(Integer等),這樣可以減少額外的內(nèi)存申請操作其次,在編碼過,我們也要避免寫一些冗余的對象申請操作,如下代碼所示代代12Stringstr="testStringstr_2=newString("test可以看到,第一行代碼里的str不會動態(tài)申請對象,而第二行的str_2外申請了一次在Jaa中也重要點,盡量使用預分配方式給出的這段代碼示例,其邏輯就是將內(nèi)存提前申請好,以避免支出運行期動態(tài)申請空間代代12StringBuildersb=newsb.append("testappend如果你在StringBuilder的構造函數(shù)中,通過參數(shù)提前指定了空間大小,并且已經(jīng)分配好,那么就可以避免在調(diào)用append的操作中,觸發(fā)額外的內(nèi)存申請操作,進而就可以 的各種數(shù)據(jù)結構類型中,如ArrayList、HashMap等的使用過,你都可以去使用。定制化內(nèi)存申請與釋放好,最后一種優(yōu)化,就是定制化內(nèi)存申請與釋放實現(xiàn)。也就是說,針對特定的務場其次,需要考慮在并發(fā)場景下,通過同步來保證線程安全性最后,要注意當堆空間不足時,有可能會觸發(fā)內(nèi)核態(tài)API調(diào)用,從而造成內(nèi)核態(tài)與用戶態(tài)切換的更大開銷(目前不確定在JVM實現(xiàn)中是否會發(fā)生這個階段,但在C/C++中會實際上,在我以往參與的很多C/C++個非常重要的性能優(yōu)化。舉個簡單的例子,針對固定大小的內(nèi)存申請操作,我可以基于隊列的出隊和入隊等類似算法實現(xiàn),來改善內(nèi)存申請與釋放速度??墒窃贘ava中,如果一些業(yè)務邏輯內(nèi),頻繁地申請和釋放對象操作對性能的影響比較大,當然是有的!這里給你介紹的一個性能優(yōu)化,就是對象池共享技術在CPU中,Cache的存取與替換都是以緩存行(Cacheline)為單位,而且在不同的CPU體系架構實現(xiàn)中,緩存行的長度也都不一樣,具體從8字節(jié)到128字節(jié)之間不等。因此,如果說我們可以把變量空間按照緩存行對齊,那么就可以提升Cache的讀寫效率,從而就既然如此,具體我們該怎這里我們先來看一個例子,這個例子主要用來說明:變量A、變量B是否在一Cacheline中,并會對Cache的操作產(chǎn)生影響如上圖的左半部分所示,如果兩個變量不在一個Cacheline中,那么在變量A、變量B時,就需要兩個Cacheline。而在圖的右側(cè),由于兩個變量在一個Cacheline中,所以只需要一個Cacheline即可。也就是說,你在編碼的過,就需要充分利用局部性原理,把經(jīng)常一起使用的變量放在一起,從而最大化地實現(xiàn)Cae的長度對齊,來優(yōu)化提升軟件的運行效率。注意CPU指令預取技術,通常情況下在串行程序中,Cacheline齊對性能的好,除此之外,我們還要知道在多核并發(fā)的場景下,由于Cacheline沒有對齊,造成的偽共享(FalseSharing),也會顯著地影響程序的運行效率。如下圖所示:已知在Core1上需要更新變量X,而Core2需要變量Y。但是由于變量X與Y在一個Cacheline中,它們會映射在相同的內(nèi)存地址上,所以每次當Core1上更新變量X之后,就會造成Core2上的變量Y對應的Cacheline失效,需要重新,進而就會影響所以在并發(fā)系統(tǒng)的設計中,針對Cacheline未對齊造成軟件性能受影響的場景,我們可以通過顯式字段的冗余來實現(xiàn)Cacheline齊,以避免這種情況的發(fā)生。不過好在,Java8中引入了sun.misc.Contended注解,它就可以針對性地識別并發(fā)場景下存在的Cacheline偽共享問題。在a,你可以借助一些nativestem.arryy方法、對象的oe方法。那么再進一步,對內(nèi)存拷貝的性能優(yōu)化極限就是零拷貝,你可以通過業(yè)務邏輯或算法優(yōu)化來盡量減少拷貝操作,從而進一步優(yōu)化性能。而對于C/C++語言來說,對一塊內(nèi)存進行修改時,使用memcopy操作性能則優(yōu)于直接賦值操作,這是因為memcopy在匯編過程,使用了特殊的匯編指令來優(yōu)化連續(xù)內(nèi)存的拷學完了這節(jié)課,我們需要明確一點,就是不同編程語言在如何高效地使用內(nèi)存上,存在不同的權衡策略,但不管是靜態(tài)類型語言(如C/C++Java(如RubPythonNode.js等),效使用內(nèi)存都是編碼性能優(yōu)化
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度城市配送貨車運輸承包服務合同
- 2025年度互聯(lián)網(wǎng)企業(yè)股東股份收購與轉(zhuǎn)讓服務協(xié)議
- 買賣交易合同(29篇)
- 2024-2025學年第25課中華人民共和國成立和向社會主義的過渡-勤徑學升高中歷史必修上同步練測(統(tǒng)編版2019)
- 2025年光伏產(chǎn)業(yè)協(xié)同發(fā)展協(xié)議
- 2025年醫(yī)院人員勞動合同格式
- 2025年中學食堂食材供應合同模板
- 2025年二手住宅購買貸款合同指南
- 2025年雙方解除雇傭合同文件
- 2025年黏膜制劑材料項目提案報告模板
- 紅樓夢詩詞全集
- 像科學家一樣思考-怎么做-怎么教-
- 苯胺合成靛紅工藝
- 三年級上冊數(shù)學脫式計算大全600題及答案
- 2024年度農(nóng)村電子商務ppt演示課件
- 計算機控制系統(tǒng) 課件 第10章 網(wǎng)絡化控制系統(tǒng)的分析與設計
- 高原反應的癥狀和處理方法
- 南京大學儀器分析習題集
- 空調(diào)維保應急預案
- 2023年高考語文全國乙卷作文范文及導寫(解讀+素材+范文)課件版
- 模塊建房施工方案
評論
0/150
提交評論