精品伊人久久大香线蕉,开心久久婷婷综合中文字幕,杏田冲梨,人妻无码aⅴ不卡中文字幕

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Android防止內(nèi)存溢出淺析
Android的虛擬機是基于寄存器的Dalvik,它的最大堆大小一般是16M。但是Android采用的是Java語言編寫,所以在很大程度上,Android的內(nèi)存機制等同于Java的內(nèi)存機制,在剛開始開發(fā)的時候,內(nèi)存的限制問題會給我們帶來內(nèi)存溢出等嚴重問題。在我們不使用一些內(nèi)存的時候,我們要盡量在Android或者其他平臺上避免在運行其他程序時,保存必要的狀態(tài),使得一些死進程所帶來的內(nèi)存問題,應該盡量在關(guān)閉程序或者保存狀態(tài)的時候釋放掉,這樣能提高系統(tǒng)在運行方面的流暢性。

Android的內(nèi)存主要表現(xiàn)在:

1. Android平臺上,長期保持一些資源的引用,造成一些內(nèi)存不能釋放,帶來的內(nèi)存泄露問題很多。比如:Context(下文中提到的Activity都是Context),在一些你需要保持你的首個類對象狀態(tài),并且把狀態(tài)傳入其他類對象中時,這樣消除掉首個類對象之前,你必須先把接收類對象釋放掉。需要注意一點的是:因為在Java或者Android內(nèi)存機制中,頂點的結(jié)點釋放前必須保證其他對象沒有調(diào)用才能被系統(tǒng)GC回收釋放。我們來看一段代碼:


  1. @Override
  2. protected void onCreate(Bundle state) {
  3. super.onCreate(state);
  4. TextViewlabel = new TextView(this);
  5. label.setText("Leaksare bad");
  6. setContentView(label);
  7. }


這個代碼的意思就是我們把一個TextView的實例加載到了我們正在運行的ActivityContext)當中,因此,通過GC回收機制,我們知道,要釋放Context,就必須先釋放掉引用他的一些對象。如果沒有,那在要釋放Context的時候,你會發(fā)現(xiàn)會有大量的內(nèi)存溢出。所以在你不小心的情況下內(nèi)存溢出是一件非常容易的事情。 保存一些對象時,同時也會造成內(nèi)存泄露。最簡單的比如說位圖(Bitmap),比如說:在屏幕旋轉(zhuǎn)時,會破壞當前保持的一個Activity狀態(tài),并且重新申請生成新的Activity,直到新的Activity狀態(tài)被保存。我們再看一段代碼:


  1. privatestatic Drawable sBackground;
  2. @Override
  3. protected void onCreate(Bundle state) {
  4. super.onCreate(state);
  5. TextView label = new TextView(this);
  6. label.setText("Leaks are bad");
  7. if (sBackground == null) {
  8. sBackground =getDrawable(R.drawable.large_bitmap);
  9. }
  10. label.setBackgroundDrawable(sBackground);
  11. setContentView(label);
  12. }


這個代碼是非常快的同時也是錯誤的。它的內(nèi)存泄露很容易出在屏幕轉(zhuǎn)移的方向上。雖然我們會發(fā)現(xiàn)沒有顯示的保存Context這個實例,但是當我們把繪制的圖連接到一個視圖的時候,Drawable就會將被View設(shè)置為回調(diào),這就說明,在上述的代碼中,其實在繪制TextView到活動中的時候,我們已經(jīng)引用到了這個Activity。鏈接情況可以表現(xiàn)為:Drawable->TextView->Context

所以在想要釋放Context的時候,其實還是保存在內(nèi)存中,并沒有得到釋放。

如何避免這種情況:主要在于。線程最容易出錯。大家不要小看線程,在Android里面線程最容易造成內(nèi)存泄露。線程產(chǎn)生內(nèi)存泄露的主要原因在于線程生命周期的不可控。下面有一段代碼:


  1. publicclass MyTest extends Activity {
  2. @Override
  3. publicvoid onCreate(BundlesavedInstanceState) {
  4. super.onCreate(savedInstanceState);
  5. setContentView(R.layout.main);
  6. new MyThread().start();
  7. }
  8. privateclass MyThread extends Thread{
  9. @Override
  10. public void run() {
  11. super.run();
  12. //do somthing
  13. }
  14. }
  15. }


代碼很簡單,但是在Android上又來新問題了,當我們在切換視圖屏幕的時候(橫豎屏),就會重新建立橫屏或者豎屏的Activity。我們形象的認為之前建立的Activity會被回收,但是事實如何呢?Java機制不會給你同樣的感受,在我們釋放Activity之前,因為run函數(shù)沒有結(jié)束,這樣MyThread并沒有銷毀,因此引用它的ActivityMytest)也有沒有被銷毀,因此也帶來的內(nèi)存泄露問題。

有些人喜歡用Android提供的AsyncTask,但事實上AsyncTask的問題更加嚴重,Thread只有在run函數(shù)不結(jié)束時才出現(xiàn)這種內(nèi)存泄露問題,然而AsyncTask內(nèi)部的實現(xiàn)機制是運用了ThreadPoolExcutor,該類產(chǎn)生的Thread對象的生命周期是不確定的,是應用程序無法控制的,因此如果AsyncTask作為Activity的內(nèi)部類,就更容易出現(xiàn)內(nèi)存泄露的問題。

線程問題的改進方式主要有:

l 將線程的內(nèi)部類,改為靜態(tài)內(nèi)部類。

l 在程序中盡量采用弱引用保存Context

2. 萬惡的bitmap。。。

Bitmap是一個很萬惡的對象,對于一個內(nèi)存對象,如果該對象所占內(nèi)存過大,在超出了系統(tǒng)的內(nèi)存限制時候,內(nèi)存泄露問題就很明顯了。。

解決bitmap主要是要解決在內(nèi)存盡量不保存它或者使得采樣率變小。在很多場合下,因為我們的圖片像素很高,而對于手機屏幕尺寸來說我們并不用那么高像素比例的圖片來加載時,我們就可以先把圖片的采樣率降低在做原來的UI操作。

如果在我們不需要保存bitmap對象的引用時候,我們還可以用軟引用來做替換。具體的實例代碼google上面也有很多。

綜上所述,要避免內(nèi)存泄露,主要要遵循以下幾點:

第一:不要為Context長期保存引用(要引用Context就要使得引用對象和它本身的生命周期保持一致)。

第二:如果要使用到Context,盡量使用ApplicationContext去代替Context,因為ApplicationContext的生命周期較長,引用情況下不會造成內(nèi)存泄露問題

第三:在你不控制對象的生命周期的情況下避免在你的Activity中使用static變量。盡量使用WeakReference去代替一個static

第四:垃圾回收器并不保證能準確回收內(nèi)存,這樣在使用自己需要的內(nèi)容時,主要生命周期和及時釋放掉不需要的對象。盡量在Activity的生命周期結(jié)束時,在onDestroy中把我們做引用的其他對象做釋放,比如:cursor.close()

其實我們可以在很多方面使用更少的代碼去完成程序。比如:我們可以多的使用9patch圖片等。有很多細節(jié)地方都可以值得我們?nèi)グl(fā)現(xiàn)、挖掘更多的內(nèi)存問題。我們要是能做到C/C++對于程序的誰創(chuàng)建,誰釋放原則,那我們對于內(nèi)存的把握,并不比JavaAndroid本身的GC機制差,而且更好的控制內(nèi)存,能使我們的手機運行得更流暢。

本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Android application context/activity context與內(nèi)存泄露
Android 避免內(nèi)存泄漏
Android內(nèi)存優(yōu)化
android的內(nèi)存優(yōu)化分析【轉(zhuǎn),超級推薦】
[Android] Android開發(fā)優(yōu)化之——從代碼角度進行優(yōu)化
Android性能優(yōu)化之內(nèi)存泄漏
更多類似文章 >>
生活服務
分享 收藏 導長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服

主站蜘蛛池模板: 利津县| 保靖县| 巴塘县| 大埔县| 克拉玛依市| 鸡泽县| 佳木斯市| 阿拉善右旗| 金川县| 玉林市| 临朐县| 湖州市| 枣强县| 九寨沟县| 资阳市| 兰溪市| 华宁县| 霍山县| 屏山县| 台前县| 涿州市| 茶陵县| 克什克腾旗| 庆城县| 吉水县| 棋牌| 津市市| 罗平县| 吉林市| 马山县| 阿拉尔市| 新化县| 岗巴县| 杨浦区| 甘洛县| 城固县| 乡宁县| 莱州市| 湘潭县| 潢川县| 金坛市|