Ⅰ android static 什麼時候被回收
android中,定義的static變數屬於全局變數,不會被GC回收,它們會一直佔用內存。直到程序結束時才會被回收。
Android是用java開發,其靜態變數的生命周期遵守Java的設計。靜態變數是在類被load的時候分配內存的,並且存在於方法區。當類被卸載的時候,靜態變數被銷毀。在PC機的客戶端程序中,一個類被載入和卸載,可簡單的等同於jvm進程的啟動和結束。
一、靜態變數在類被載入的時候分配內存。
當啟動一個app的時候,系統會創建一個進程,此進程會載入一個Dalvik VM的實例,然後代碼就運行在DVM之上,類的載入和卸載,垃圾回收等事情都由DVM負責。也就是說在進程啟動的時候,類被載入,靜態變數被分配內存。
二、靜態變數在類被卸載的時候銷毀。
一般情況下,所有的類都是默認的ClassLoader載入的,只要ClassLoader存在,類就不會被卸載,而默認的ClassLoader生命周期是與進程一致的。
Ⅱ android程序JNI資源自動回收問題。
看不懂請講國語
Ⅲ android開發問題: app切到後台,然後打開很多app,之後這個app的資源會被回收,重新打
@Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
getSupportFragmentManager().putFragment(outState, "mContent", mContent);
}
mContent 是你要緩存的fragment
取得時候可以從Activity(FragmentActivity)的onCreate方法的Bundle savedInstanceState取出。
if (savedInstanceState != null) {
mContent = (BaseFragment) getSupportFragmentManager().getFragment(savedInstanceState, "mContent");
Ⅳ android service 什麼情況下會被系統回收
android service 開機啟動後被被自動關閉掉原因:
Android 系統對於內存管理有自己的一套方法,為了保障系統有序穩定的運信,系統內部會自動分配,控製程序的內存使用。當系統覺得當前的資源非常有限的時候,為了保 證一些優先順序高的程序能運行,就會殺掉一些他認為不重要的程序或者服務來釋放內存。這樣就能保證真正對用戶有用的程序仍然再運行。如果你的 Service 碰上了這種情況,多半會先被殺掉。但如果你增加 Service 的優先順序就能讓他多留一會,我們可以用 setForeground(true) 來設置 Service 的優先順序。
默認啟動的 Service 是被標記為 background,當前運行的 Activity 一般被標記為 foreground,也就是說你給 Service 設置了 foreground 那麼他就和正在運行的 Activity 類似優先順序得到了一定的提高。當讓這並不能保證你得 Service 永遠不被殺掉,只是提高了他的優先順序。
Ⅳ Android系統回收activity行為
安卓本身不支持內存分頁交換技術,是通過回收activity的方式來回收內存的。.activity處於onPause或者onStop狀態時,假如系統資源不足(內存不足),會被系統回收釋放。
系統回收內存會存在兩種行為:
1.當APP不在前台的時候,資源緊張,強殺APP進程並回收activity,這種情況不會調用生命周期的onDestroy方法。可以用「開發者選項」中的「限制後台進程數」來模擬這種情況。
2.當APP在前台,系統資源不足的時候,會回收APP處於pause或stop狀態的Activity,這種情況不殺進程,但會調用onDestroy方法。可以用「開發者選項」中的「不保留活動」打開,來模擬這種情況。
因此,平時在onCreate方法里注冊監聽register,在onDestroy方法里反注冊unregister不會有問題。因為假如是情況1,進程被殺掉了,不執行onDestroy方法也沒事,進程都沒了,就無所謂內存泄露的事。假如是情況2,那麼會執行onDestroy方法反注冊。
歡迎留言討論,或指正問題。
Ⅵ 如何防止android應用中的service被系統回收
永不被kill是不可能的,android系統應用都有可能會被kill,不要說用戶應用了,只能說被kill以後還能重新啟動。
Android中,當Service被kill後,如果重啟需要使用BroadcastReceiver來實現,即廣播接收者,例如利用BroadcastReceiver注冊網路廣播或者開關機廣播,當接收到廣播後直接啟動service,這樣就可以保證service被kill後,自動啟動。
實現代碼:
1.在配置文件AndroidManifest.xml中向系統注冊BroadcastReceiver
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
2.需要添加相應許可權
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
3.在Receiver中就可以添加開機,或者網路狀態改變後需要進行的操作
public class BootCompletedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
}
}
4.執行操作,Intent intent = new Intent(context,Service.class); context.startService(intent); 這樣即可開機,或者網路狀態改變後啟動Service了。
Ⅶ Android App內存優化
內存優化就是對內存問題的一個預防和解決,做內存優化能讓應用掛得少、活得好和活得久。
掛的少:
「掛」指的是 Crash,內存問題導致 Crash 的具體表現就是內存溢出異常 OOM。
活得好:
活得好指的是使用流暢,Android 中造成界面卡頓的原因有很多種,其中一種就是由內存問題引起的。內存問題之所以會影響到界面流暢度,是因為垃圾回收(GC,Garbage Collection),在 GC 時,所有線程都要停止,包括主線程,當 GC 和繪制界面的操作同時觸發時,繪制的執行就會被擱置,導致掉幀,也就是界面卡頓。
活得久:
活得久指的是我們的應用在後台運行時不會被幹掉。Android 會按照特定的機制清理進程,清理進程時優先會考慮清理後台進程。清理進程的機制就是LowMemoryKiller。在 Android 中不同的進程有著不同的優先順序,當兩個進程的優先順序相同時,低殺會優先考慮幹掉消耗內存更多的進程。也就是如果我們應用佔用的內存比其他應用少,並且處於後台時,我們的應用能在後台活下來,這也是內存優化為我們應用帶來競爭力的一個直接體現。
內存佔用是否越少越好?
當系統 內存充足 的時候,我們可以多用 一些獲得更好的性能。當系統 內存不足 的時候,我們希望可以做到 」用時分配,及時釋放「。內存優化並不能一刀切。
我們都知道,應用程序的內存分配和垃圾回收都是由Android虛擬機完成的,在Android 5.0以下,使用的是Dalvik虛擬機,5.0及以上,則使用的是ART虛擬機。
Android虛擬機Dalvik和ART
1、內存區域劃分
詳細請看以下兩篇文章(建議全看):
java內存四大區_JVM內存區域劃分
Android 內存機制
2、內存回收
垃圾收集的標記演算法(找到垃圾):
垃圾收集演算法(回收垃圾):
引用類型:強引用、軟引用、弱引用、虛引用
對象的有效性=可達性+引用類型
JAVA垃圾回收機制-史上最容易理解看這一篇就夠了
Android:玩轉垃圾回收機制與分代回收策略
android中還存在低殺機制,這種情況屬於系統整機內存不足,直接把應用進程殺掉的情況。
Android後台殺死系列:LowMemoryKiller原理
1、內存溢出
系統會給每個App分配內存空間也就是heap size值,當app佔用的內存加上申請的內存超過這個系統分配的內存限額,最終導致OOM(OutOfMemory)使程序崩潰。
通過命令 getprop |grep dalvik.vm.heapsize 可以獲取系統允許的最大
注意:在設置了heapgrowthlimit的狀況下,單個進程可用最大內存為heapgrowthlimit值。在android開發中,若是要使用大堆,須要在manifest中指定android:largeHeap為true,這樣dvm heap最大可達heapsize。
關於heapsize & heapgrowthlimit
2、內存泄漏
Android系統虛擬機的垃圾回收是通過虛擬機GC機制來實現的。GC會選擇一些還存活的對象作為內存遍歷的根節點GC Roots,通過對GC Roots的可達性來判斷是否需要回收。內存泄漏就是 在當前應用周期內不再使用的對象被GC Roots引用,造成該對象無法被系統回收,以致該對象在堆中所佔用的內存單元無法被釋放而造成內存空間浪費,使實際可使用內存變小。簡言之,就是 對象被持有導致無法釋放或不能按照對象正常的生命周期進行釋放。
Android常見內存泄漏匯總
3、內存抖動
指的是在短時間內大量的新對象被實例化,運行時可能無法承載這樣的內存分配,在這種情況下就會導致垃圾回收事件被大量調用,影響到應用程序的UI和整體性能,最終可能導致卡頓和OOM。
常見情況:在一些被頻繁調用的方法內不斷地創建對象。例如在View 的onDraw方法內new 一些新的對象。
注意內存抖動也會導致 OOM,主要原因有如下兩點:
1、Android Studio Profiler
作用
優點
內存抖動問題處理實戰
理解內存抖動的概念的話,我們就能明白只要能找到抖動過程中所產生的對象及其調用棧,我們就能解決問題,剛好Android Studio 的Porfiler裡面的Memory工具就能幫我們記錄下我們操作過程中或靜止界面所產生的新對象,並且能清晰看到這些對象的調用棧。
選擇Profile 中 的Memory ,選擇 Record Java/Kotlin allocations,再點擊Record開始記錄, Record Java/Kotlin allocations 選項會記錄下新增的對象。
操作完成之後,點擊如圖所示的紅腦按鈕,停止記錄。
停止記錄後,我們就可以排序(點擊 Allocations可以排序)看看哪些對象或基本類型在短時間被頻繁創建多個,點擊這些新增的對象就可以看到它的完成的調用鏈了,進而就找找到導致內存抖動的地方在哪裡了。
2、利用DDMS 和 MAT(Memory Analyzer tool)來分析內存泄漏
我們利用工具進行內存泄漏分析主要是用對比法:
a.先打開正常界面,不做任何操作,先抓取一開始的堆文件。
b.一頓胡亂操作,回到原來操作前的界面。主動觸發一兩次GC,過10秒再抓取第二次堆文件。
c.通過工具對比,獲取胡亂操作後新增的對象,然後分析這些新增的對象。
DDMS作用:抓取堆文件,主動觸發GC。(其實也是可以用Android Studio 的Profile裡面的Memory工具來抓取堆文件的,但是我這邊在利用Profile 主動觸發gc 的時候會導致程序奔潰,也不知道是不是手機的問題,所以沒用Android Studio的Profiler)
MAT作用:對堆文件進行對比,找到多出的對象,找到對象的強引用調用鏈。
以下是詳細的過程:
步驟1.打開DDMS,選擇需要調試的應用,打開初始界面,點擊下圖的圖標(Dump Hprof File)先獲取一次堆文件。
步驟2.對應用隨便操作後,回到一開始的界面,先多觸發幾次GC ,點擊下圖的圖標(Cause Gc)來主動觸發GC,然後再次點擊 Dump Hprof File 圖標來獲取堆文件。
步驟3.通過Android Studio Profile 或者 DDMS mp 的堆文件無法在MAT 打開,需要藉助android sdk包下的一個工具hprof-conv.exe來轉換。
格式為 hprof-conv 舊文件路徑名 要轉換的名稱;
例如:hprof-conv 2022-04-13_17-54-40_827.hprof change.hprof
步驟4.把兩份堆文件導入MAT,然後選擇其中第二次獲取的堆文件,點擊 如圖所示的 Histogram查看。
步驟5.點擊下圖圖標,Compare To Another Heap Dump ,選擇另一份堆文件。
6.會得出下圖所示的 Hitogram 展示,我們主要看Objects 這一列。 如下圖所示 「+ 2」 則代表前面兩份堆文件對比,這個對象多了兩個,我們主要就是要分析這些多了出來,沒有被回收的對象。
7.加入我們從增加的對象中,看到了MainActivity ,則需要從一開始打開的Hitogram 展示裡面找到這個對象的調用棧。如下圖所示,搜索MainActivity
8.看到下圖所示解僱,然後滑鼠右鍵點擊下圖紅色圈圈著的MainActivity ,選擇 Merger Shortest Paths to Gc Roots ,再選擇 exclude all phantom/weak/soft etc.references ,就可以看到這個MainActivity 對象的強引用鏈,至此我們就可以找到MainActivity對象是被什麼引用導致無法回收了。
3、內存泄露檢測神器之LeakCanary(線下集成)
自行學習了解,接入簡單,使用簡單,基本可以解決大部分內存泄漏問題。
github地址 : https://github.com/square/leakcanary/
學習地址 : https://square.github.io/leakcanary/changelog/#version-22-2020-02-05
針對內存抖動的建議:
針對內存泄漏問題的建議:
針對內存溢出問題的建議(主要就是要減少內存佔用):
建議參考:
深入探索 Android 內存優化(煉獄級別)
對於 優化的大方向,我們應該優先去做見效快的地方,主要有以下三部分:內存泄漏、內存抖動、Bitmap。完善監控機制也是我們的重點,能幫助我們對內存問題快速分析和處理。
參考:
深入探索 Android 內存優化(煉獄級別)
Ⅷ android進程被系統回收(殺死)
Activity綁定Service,那麼這個service的生命周期跟activity相關。會隨著activity結束而結束。
綁定的service跟activity是同一個進程的。
如果service配置一個單獨的進程,應該是通過startService來啟動的,bindService不行吧?
系統資源不足時,會有一個策略來回收進程,優先順序的回收順序是 Empty process、Background process、Service process、Visible process、Foreground process。
參見www.cnblogs.com/bastard/archive/2012/08/17/2644169.html
Ⅸ 現在android上的Dalvik是用哪個垃圾回收演算法
Dalvik虛擬機使用Mark-Sweep演算法來進行垃圾收集。顧名思義,Mark-Sweep演算法就是為Mark和Sweep兩個階段進行垃圾回收。其中,Mark階段從根集(Root Set)開始,遞歸地標記出當前所有被引用的對象,而Sweep階段負責回收那些沒有被引用的對象。
Ⅹ 如何管理Android手機剩餘內存
大家知道要如何管理Android手機剩餘內存嗎?管理Android手機剩餘內存有什麼方法?下面一起來看看!
其實大家不用那麼在意android手機剩餘內存的大小。
很多人都是把使用其他系統的習慣帶到了android手機上,不是所有的智能手機系統都一樣的。android大多數應用沒有退出的設計其實是有道理的,這和系統對進程的調度機制有關系。如果你知道java,就能更清楚這機制了。其實和java的垃圾回收機制類似,系統有一個規則來回收內存。進行內存調度有個閥值,只有低於這個值系統才會按一個列表來關閉用戶不需要的東西。當然這個值默認設置得很小,所以你會看到內存老在很少的數值徘徊。但事實上他並不影響速度。相反加快了下次啟動應用的速度。這本來也是android的優勢之一,如果人為去關閉進程,沒有太大必要。特別是自動關進程的軟體。
為什麼內存少的時候運行大型程序會慢呢?
其實很簡單,在內存剩餘不多時打開大型程序,會觸發系統自身的調進程調度策略,這是十分消耗系統資源的操作,特別是在一個程序頻繁向系統申請內存的時候。這種情況下系統並不會關閉所有打開的進程,而是選擇性關閉,頻繁的調度自然會拖慢系統。
進程管理軟體到底還有存在的價值嗎?
其實還是有的,在運行大型程序之前,你可以手動關閉一些進程釋放內存,可以顯著的提高運行速度。但一些小程序,完全可交由系統自己管理。很多朋友還有個疑問,如果不關程序是不是會更耗電?這里也解釋一下,android的應用在被切換到後台時,它其實已經被暫停了,並不會消耗cpu資源,只保留了運行狀態。所以為什麼有的程序切出去重新進入,還會到主界面。但是,一個程序如果想要在後台處理些東西,如音樂播放,它就會開啟一個服務,服務可在後台持續運行,所以在後台耗電的也只有帶服務的應用了。這個在進程管理軟體里能看到,名字是service。所以沒有帶服務的應用在後台是完全不耗電的,沒有必要關閉。這種設計本來就是一個非常好的設計,下次啟動程序時,會更快,因為不需要讀取界面資源,何必要關掉他們抹殺這個android的優點呢?
為什麼android應用看起來那麼耗內存?
大家知道,android上的應用是java,當然需要虛擬機,而android上的應用是帶有獨立虛擬機的,也就是每開一個應用就會打開一個獨立的虛擬機。這樣設計的原因是可以避免虛擬機崩潰導致整個系統崩潰,但代價就是需要更多內存。
至於為什麼開了大程序或者開了好幾個程序之後切換會變慢,具體分析如下:
已經開啟了一個大程序,佔用70%內存,如果再想運行一個程序,此時還需要50%的內存,則就需要一個從大程序佔用的內存中釋放或者壓縮的過程,所以表現出來的就是慢一會兒。
已經開啟了幾個程序共佔用內存80%,運行新程序時又需要20%的內存,系統內存因為沒見過剩餘0的時候,也就是應該剩一部分空閑內存,那麼就需要從之前開啟的這幾個程序中選擇一個或者幾個來關閉,這一過程也需要耗費系統資源,所以會慢一會兒。也就是說你手動去結束程序的時候,就是替系統在釋放內存,就算你不去結束,在需要內存的時候系統也會自動結束程序釋放內存。
不在後台運行的程序(沒服務的),即使不結束也不會耗電。在後台運行的(有服務的`)程序,如一些播放器或實時監控的軟體,自然會耗電。這就說明結束進程並不是沒用,我們只需要看哪個帶服務耗電哪個程序後台一直在運行,看服務就能看出來,這樣的軟體如果用不到的時候就結束了吧。
以QQ舉例,正常的退出,會在進程管理里留下qq的運行過的狀態,但不耗電不佔 cpu,如果你只是切換出去(按房子鍵而不是退出)那麼自然會耗電,因為程序還在運行,QQ還在線呢。
這里就有個要注意的地方了,雖然房子鍵和那個返回鍵都可以將程序切換出去,但是兩者的效果差異是很大的,返回鍵可以視作程序已經退出了,而按房子鍵,則是將程序切換到了後台來運行,軟體並沒有退出哦!
以上這些設計都是為了確保了android的穩定性,正常情況下最多單個程序崩潰,但整個系統不會崩潰,也永遠沒有內存不足的提示出現。大家可能是被windows毒害得太深了,總想保留更多的內存,但實際上這並不一定會提升速度,相反卻喪失了程序啟動快的這一系統特色,得不償失。大家不妨換種觀念習慣來使用android系統。