当前位置: 代码迷 >> Android >> 杞?浇-android bit地图 oom 鍒嗘瀽
  详细解决方案

杞?浇-android bit地图 oom 鍒嗘瀽

热度:351   发布时间:2016-05-01 12:38:56.0
杞?浇--android bitmap oom 鍒嗘瀽
鍘熸枃鍑哄?:http://labs.ywlx.net/?p=3351

android 鐢辫В鏋恇itmap寮曡捣鐨勫唴瀛樻孩鍑洪棶棰?
鍙戣〃浜?2012/10/28 鐢?peibingqing
鏈?杩戝湪鍋氫竴娆惧?闃叉父鎴忥紝鐢ㄧ殑浜媠urfaceview妗嗘灦锛岀敱浜庡浘鐗囪繃澶氾紝鑰屼笖娓告垙杩囩▼涓?兘闇?瑕佽繖浜涘浘鐗囷紝鎵?浠ュ姞杞芥垚bitmap鍚庨?犳垚OOM锛坥ut of memory锛夊紓甯搞?備笅闈㈡槸鎴戜竴姝ヤ竴姝ユ壘瑙e喅姝ら棶棰樼殑绾?綍锛屽啀姝ゅ垎浜?紝甯屾湜瀵逛互鍚庡嚭鐜版?闂??鐨勫紑鍙戣?呮湁鎵?甯?姪銆?

绗?竴锛氬嚭鐜伴棶棰橈紝鎴戠殑娴嬭瘯鎵嬫満鏄?銆?android鎿嶄綔绯荤粺锛屼笉浼氬嚭鐜皁om闂??锛屼絾鏄?湪鑰佹澘鐨刟ndroid4.2涓婂嵈鍑虹幇浜嗛棶棰橈紝鍥犱负鏄痮om锛屾墍浠ユ垜棣栧厛鎯冲埌鐨勬槸鎵嬪姩鏀瑰彉鎵嬫満鐨勫唴瀛樺ぇ灏忛檺鍒躲?傜綉涓婃湁浜涘笘瀛愯?鍙?互閫氳繃鍑芥暟璁剧疆搴旂敤鐨凥EAP SIZE鏉ヨВ鍐宠繖涓?棶棰橈紝鍏跺疄鏄?笉瀵圭殑銆?VMRuntime.getRuntime().setMinimumHeapSize(NewSize); 鍫嗭紙HEAP锛夋槸VM涓?崰鐢ㄥ唴瀛樻渶澶氱殑閮ㄥ垎锛岄?氬父鏄?姩鎬佸垎閰嶇殑銆傚爢鐨勫ぇ灏忎笉鏄?竴鎴愪笉鍙樼殑锛岄?氬父鏈変竴涓?垎閰嶆満鍒舵潵鎺у埗瀹冪殑澶у皬銆傛瘮濡傚垵濮嬬殑HEAP鏄?M澶э紝褰?M鐨勭┖闂磋?鍗犵敤瓒呰繃75%鐨勬椂鍊欙紝閲嶆柊鍒嗛厤鍫嗕负8M澶э紱褰?M琚?崰鐢ㄨ秴杩?5%锛屽垎閰嶅爢涓?6M澶с?傚?掕繃鏉ワ紝褰?6M鐨勫爢鍒╃敤涓嶈冻30%鐨勬椂鍊欙紝缂╁噺瀹冪殑澶у皬涓?M澶с?傞噸鏂拌?缃?爢鐨勫ぇ灏忥紝灏ゅ叾鏄?帇缂╋紝涓?鑸?細娑夊強鍒板唴瀛樼殑鎷疯礉锛屾墍浠ュ彉鏇村爢鐨勫ぇ灏忓?鏁堢巼鏈変笉鑹?奖鍝嶃?侻ax Heap Size锛屾槸鍫嗗唴瀛樼殑涓婇檺鍊硷紝Android鐨勭己鐪佸?兼槸16M锛堟煇浜涙満鍨嬫槸24M锛夛紝瀵逛簬鏅??氬簲鐢ㄨ繖鏄?笉鑳芥敼鐨勩?傚嚱鏁皊etMinimumHeapSize鍏跺疄鍙?槸鏀瑰彉浜嗗爢鐨勪笅闄愬?硷紝瀹冨彲浠ラ槻姝㈣繃浜庨?绻佺殑鍫嗗唴瀛樺垎閰嶏紝褰撹?缃?渶灏忓爢鍐呭瓨澶у皬瓒呰繃涓婇檺鍊兼椂浠嶇劧閲囩敤鍫嗙殑涓婇檺鍊硷紝瀵逛簬鍐呭瓨涓嶈冻娌′粈涔堜綔鐢ㄣ??setTargetHeapUtilization(float newTarget) 鍙?互璁惧畾鍐呭瓨鍒╃敤鐜囩殑鐧惧垎姣旓紝褰撳疄闄呯殑鍒╃敤鐜囧亸绂昏繖涓?櫨鍒嗘瘮鐨勬椂鍊欙紝铏氭嫙鏈轰細鍦℅C鐨勬椂鍊欒皟鏁村爢鍐呭瓨澶у皬锛岃?瀹為檯鍗犵敤鐜囧悜涓?櫨鍒嗘瘮闈犳嫝銆傚湪鎵嬫満涓婅繘琛屼簡澶氭?娴嬭瘯锛岀‘瀹炰笉濂戒娇锛屽湪姝わ紝鎴戞柇浜嗘敼鍙樺唴瀛橀檺鍒剁殑鏂规硶銆?

绗?簩锛氭煡鎵惧嚭鐜伴棶棰樼殑鍘熷洜銆?锛屽湪缃戜笂鎼滅储bitmap鍐呭瓨婧㈠嚭锛屾壘鍒板緢澶氳?鏄?洜涓哄浘鐗囧ぇ灏忓紩璧风殑姝ら棶棰樸?傝?瀵熸垜鐨勮祫婧愭枃浠讹紝娌℃湁澶?ぇ鐨勫浘鐗囷紝鍙?槸鍥剧墖鏁伴噺杩囧?锛屾湁灏嗚繎900寮狅紝鍒嗗埆鎵惧嚭涓?寮犳渶澶х殑鍥剧墖鍜屽嚑寮犳瘮杈冨ぇ鐨勫浘鐗囷紝鍗曠嫭娴嬭瘯锛屾病鏈夊彂鐜伴棶棰樸?傛柟娉?鎺掗櫎銆?

2锛屾棦鐒跺浘鐗囨暟閲忚繃澶氾紝绐佺牬鐐瑰彲鑳藉氨鏄?浘鐗囨暟閲忛棶棰樸?備簬鏄?垎鍒?壘浜?00锛?00锛?00鍥剧墖杩涜?娴嬭瘯锛屽湪500宸﹀彸鐨勬椂鍊欓亣鍒伴敊璇?紝閫氳繃瀹濆摜鐭ラ亾浜嗗皢灏忓浘鐗囨暣鍚堝瓨鏀惧埌涓?寮犲ぇ鍥剧殑鏂规硶锛屼互姝ゆ潵鍑忓皯鍥剧墖鐨勬暟閲忥紝浣嗘槸浠旂粏鎯虫兂锛屽姞杞芥垚bitmap鐨勬椂鍊欒繕鏄??鍒囧壊鎴愬皬鍥剧敓鎴恇itmap锛屾墍浠ュ?姝ゆ柟娉曡〃绀烘??鐤戙?傜敱浜庝互鍓嶆病鐢ㄨ繃姝ゆ柟娉曪紝璇曡瘯涔熸棤濡ㄣ?傛墍鐢ㄥ埌鐨勫伐鍏锋槸gdx鈥攖exturepackger锛屽畠鍙?槸涓?涓?伐鍏凤紝杩欓噷灏变笉澶氳?浜嗐?傛祴璇曠殑鏈?缁堢粨鏋滄槸杩樻槸oom銆傛柟娉?鎺掗櫎銆?

3锛岀幇鍦ㄧ湅鏉ワ紝鏃㈢劧涓嶆槸鍥剧墖鏁伴噺鐨勯棶棰橈紝鑰屼笖浼氬湪500寮犲乏鍙崇殑鏃跺?欐姤閿欙紝閭e氨鍙?兘鏄?崰鐢ㄥ唴瀛樺ぇ灏忕殑闂??浜嗭紝Android鎵嬫満鏈夊唴瀛橀檺鍒讹紝浣嗘槸鎴戠殑鍥剧墖澶у皬鍙堝ぇ浜庤繖涓?檺鍒讹紝杩欒?鎴戝ご鐤间簡寰堥暱鏃堕棿锛岀爺绌跺浗澶栫殑涓?浜涙枃绔狅紝浠庝腑鍙戠幇浜嗕竴浜涙湁鐢ㄧ殑淇℃伅锛岃繖浜涗俊鎭?兘澶熷姞娣变綘瀵笰ndroid鐨勮В鏋恇itmap鏈哄埗鐨勭悊瑙o紝鍦ㄦ?鍒嗕韩锛?

As of Honeycomb Bitmap data is allocated in the VM heap.

浣滀负铚傜獫浣嶅浘鏁版嵁鏄?湪VM鍒嗛厤鍫嗐??

There is a reference to it in the VM heap (which is small), but the actual data is allocated in the Native heap by the underlying Skia graphics library. 鏈変竴涓?紩鐢ㄥ湪VM鍫?灏?,浣嗗疄闄呯殑鏁版嵁鏄?湪鏈?満鍫嗗垎閰嶇敱搴曞眰Skia鍥惧舰搴撱??
Unfortunately, while the definition of BitmapFactory.decode鈥?) says that it returns null if the image data could not be decoded, the Skia implementation (or rather the JNI glue between the Java code and Skia) logs the message you鈥檙e seeing (鈥淰M won鈥檛 let us allocate xxxx bytes鈥? and then throws an OutOfMemory exception with the misleading message 鈥渂itmap size exceeds VM budget鈥? 涓嶅垢鐨勬槸,铏界劧BitmapFactory.decode鐨勫畾涔夆??)琛ㄧず,瀹冭繑鍥瀗ull濡傛灉鍥惧儚鏁版嵁涓嶈兘瑙g爜,Skia瀹炵幇(鎴栬?呰?JNI鑳朵箣闂寸殑Java浠g爜鍜孲kia)鏃ュ織娑堟伅浣犵湅鍒?鈥淰M涓嶄細璁╂垜浠?垎閰峹xxx瀛楄妭鈥?,鐒跺悗鎶涘嚭涓?涓狾utOfMemory寮傚父涓庤?瀵间俊鎭??濅綅鍥剧殑澶у皬瓒呰繃VM棰勭畻鈥濄??
The issue is not in the VM heap but is rather in the Native heap. 杩欎釜闂??涓嶆槸鍦╒M鍫嗚?屾槸鍦ㄦ湰鏈哄爢銆?
The Nat茂ve heap is shared between running applications, so the amount of free space depends on what other applications are running and their bitmap usage. 鏈?満鍫嗘槸姝e湪杩愯?鐨勫簲鐢ㄧ▼搴忎箣闂村叡浜?鍥犳?绌洪棽绌洪棿鐨勫ぇ灏忓彇鍐充簬鍏朵粬杩愯?绋嬪簭,浠栦滑浣跨敤鐨勪綅鍥俱??

However, I have found that getNativeHeapFreeSize() and getNativeHeapSize() are not reliable. 鐒惰??鎴戝彂鐜癵etNativeHeapFreeSize()鍜実etNativeHeapSize()鏄?笉鍙?潬鐨勩??

The Native heap size varies by platform. 鏈?満鍫嗗ぇ灏忎笉鍚岀殑骞冲彴銆?
So at startup, we check the maximum allowed VM heap size to determine the maximum allowed Native heap size. 鎵?浠ュ湪鍚?姩鏃?鎴戜滑妫?鏌ユ渶澶у厑璁竀M鍫嗗ぇ灏忔潵纭?畾鏈?澶у厑璁告湰鏈哄爢澶у皬銆?

鈥淏itmap data is not allocated in the VM heap鈥?鈥?it is allocated on the VM heap as of Honeycomb 鈥滀綅鍥炬暟鎹?笉鏄?湪VM鍒嗛厤鍫嗏?濃?斺?旇繖鏄疺M鍒嗛厤鐨勫爢鍦ㄨ渹绐漎es. 鏄?殑銆?As of Honeycomb (v3.0), bitmap data is allocated on the VM heap. 浣滀负铚傜獫(v3.0),浣嶅浘鏁版嵁鍫嗕笂鍒嗛厤VM銆?So all of the above only applies to Gingerbread (v2.3.x) and before 鎵?浠ユ墍鏈変笂杩板彧閫傜敤浜庡?楗?v2 3 x)鍜屼箣鍓?

杩欎簺淇℃伅闆堕浂鏁f暎锛屼絾鏄?笉闅惧彂鐜帮紝闂??鐨勫師鍥犲氨鍦ㄤ簬鏍规嵁Android鐗堟湰鐨勪笉鍚岋紝bitmap data瀛樻斁鐨勪綅缃?槸涓嶅悓鐨勶紝3.0浠ュ墠鏄?垎閰嶅湪native heap涓婏紝3.0浠ュ悗鏄?垎閰嶅湪VM heap涓娿??

涓轰簡楠岃瘉杩欎釜闂??锛屾垜浠?渶瑕佹姄鍘籬eap蹇?収锛屼紬鎵?鍛ㄧ煡锛宔clipse涓?殑ddms鍙?互鏌ョ湅heap淇℃伅锛屼絾鏄?笉澶熷叏闈?紝杩欓噷鎴戠敤鍒颁簡adb shell dumpsys meminfo+鍖呭悕 杩欐潯鍛戒护鏉ユ煡鐪媓eap淇℃伅锛屽?姣斾袱涓?満瀛愮殑涓嶅悓濡備笅锛?



2.2鐨?



4.0

浠庝腑涓嶉毦鍙戠幇锛宐itmap鐨勫瓨鏀句綅缃?牴鎹瓵ndroid鐗堟湰鐨勪笉鍚岀湡鐨勬湁鎵?涓嶅悓銆傚ソ浜嗭紝涓嬮潰灏辨槸鎵惧嚭鎬庝箞鎶婂浘鐗囧瓨鏀惧埌native heap閲屽氨琛屼簡锛孊itmapFactory閲屽氨閭d箞鍑犱釜decode鏂规硶锛屽緢瀹规槗鎵惧埌BitmapFactory .decodeStream灏卞彲浠ヨВ鍐炽?備笅闈㈣创涓?涓嬩唬鐮侊細

BitmapFactory.Options options = new BitmapFactory.Options();

options.inPreferredConfig = Config.ARGB_8888;

options.inPurgeable = true;// 鍏佽?鍙?竻闄?

options.inInputShareable = true;// 浠ヤ笂options鐨勪袱涓?睘鎬у繀椤昏仈鍚堜娇鐢ㄦ墠浼氭湁鏁堟灉

String sname = String.format( 鈥渪xx.png鈥? sTowerStyle, j, sDirction, i);

InputStream is = am.open(sname);

arrBmp[ iBmpIndex] = BitmapFactory .decodeStream(is, null, options);

ok鎼炲畾鏀跺伐銆?

灏忛棶棰樺ぇ鍙戠幇锛?.閬囧埌闂??锛屼笉瑕佹?ヨ簛銆傛渶鍒濋亣鍒拌繖涓?棶棰樼殑鏃跺?欎互涓哄緢濂借В鍐筹紝璇曚簡鍑犵?鏂规硶鍚庤繕鏄?В鍐充笉浜嗭紝鍐呭績闅惧厤浼氭湁鎸?触鎰燂紝杩欎釜鏃跺?欙紝鏈?闇?瑕佺殑鏄??愬績銆?

2.缃戜笂鏈夊緢澶氳祫婧愶紝浣嗘槸鑳戒笉鑳芥煡寰楀埌灏辨槸鑷?繁鐨勯棶棰樹簡锛屾垜鍙戠幇閭d簺缂栫▼鑰佹墜浠?煡鎵鹃棶棰樻?绘槸鑳藉?鍑嗙‘瀹氫綅锛屽揩閫熺殑鎵惧埌瑙e喅鏂规硶銆備互鍚庤?鍔犲己杩欐柟闈㈢殑閿荤偧銆?

3.鍥藉唴鐨勮祫婧愬ぇ澶氬亸鍚戣В鍐抽棶棰橈紝鍥藉?鐨勮祫婧愬ぇ澶氬亸鍚戝垎鏋愰棶棰橈紝鎵?浠ユ湁鐨勬椂鍊欒繕鏄?渶瑕佸?鐪嬬湅澶栨枃鐨勪竴浜涜祫鏂欍?傚綋鐒惰繖闇?瑕佷笉閿欑殑鑻辨枃鍔熷簳銆傚綋鍒濈湅澶栨枃鐨勮祫鏂欙紝澶撮兘澶т簡銆傝繖鏄?渶瑕佸姞寮虹殑涓?涓?柟闈???

Dance In Wind     28/10/12
  相关解决方案