android防止記憶體溢位淺析(二)
上次討論的 由於Bitmap引起的記憶體溢位相對比較容易發現,這次我們來看看相對比較難以發現的引起記憶體溢位的兩種情況。
一,Context引起的記憶體溢位:
在Android平臺上,長期保持一些資源的引用,造成一些記憶體不能釋放,帶來的記憶體洩露問題很多。比如Context。
android中的很多資原始檔都需要一個Context引用來載入,如果這些資源沒有被釋放,那麼Context的引用不為null,造成對應的Activity即使 呼叫了finish()但其佔有的記憶體依然不能被釋放。這是 因為在Java或者Android記憶體機制中,頂點的結點釋放前必須保證其他物件沒有呼叫才能被系統GC回收釋放。我們來看一段程式碼:
SoundManager.getInstance(this).play(SoundManger.MAIN_BG_SOUND);
從這段程式碼可以看出,聲音管理類是一個單例,它對於整個應用程式來說是全域性的,在進入應用的時候建立這個單例直到應用結束,這個單例才會被釋放。大家可以看到這個類在得到單例的時候需要傳遞一個Context物件作為引數,因為要利用Context來載入聲音資源。這就導致如果當前Activity呼叫了finish()全依然不能被GC,因為聲音管理類是全域性的,它持有了當前Activity的應用,阻止了其被GC。 解決的辦法是儘量使用全域性的Context來載入資源。修改如下:
SoundManager.getInstance(this.getApplicationContext).play(SoundManger.MAIN_BG_SOUND);
2 , Thread 執行緒引起的記憶體溢位:
先看程式碼:
private class MyThread extends Thread
{
@Override
public void run()
{
super.run();
while(bFlag)
{
//do somthing
}
}
}
MyThread mThread = new MyThread();
mThread.start();
這端程式碼 在主執行緒裡新開了一個執行緒,並且線上程裡迴圈處理一些邏輯。問題在於 如果控制執行緒結束的bFlag如果在Activity銷燬時沒有置為 false 將會產生很嚴重的後果。執行緒的一個特點是生命週期的不可控。如果Activity銷燬時,沒有結束執行緒的執行,那麼不僅阻止了Activity被GC,而且大大降低了程式的效能。假如,再重新進入這個Activity,那麼又建立了一個死迴圈的執行緒,而之前的那個執行緒依然在執行,這樣程式就會非常的卡。所以 一定要注意,銷燬Activity時一定要結束執行緒。
總而言之,想要避免context 相關的記憶體洩漏 ,記住以下幾點:
a.不要對activity 的context 長期引用( 一個activity 的引用的生存週期應該和activity 的生命週期相同)
b.試著使用關於application的 context 來替代和activity相關的context
c.如果一個acitivity 的非靜態內部類的生命週期不受控制,那麼避免使用它;使用一個靜態的內部類並且對其中的activity 使用一個弱引用。解決這個問題的方法是使用一個靜態的內部類,並且對它的外部類有一WeakReference,就像在ViewRoot中內部類W所做的就是這麼個例子。
相關文章
- 【記憶體洩漏和記憶體溢位】JavaScript之深入淺出理解記憶體洩漏和記憶體溢位記憶體溢位JavaScript
- Java棧溢位|記憶體洩漏|記憶體溢位Java記憶體溢位
- 記憶體溢位記憶體溢位
- Java記憶體溢位Java記憶體溢位
- 記憶體溢位和記憶體洩露記憶體溢位記憶體洩露
- Android-Fragment 切換造成記憶體溢位,導致記憶體增長AndroidFragment記憶體溢位
- JVM——記憶體洩漏與記憶體溢位JVM記憶體溢位
- 阿里大佬講解Java記憶體溢位示例(堆溢位、棧溢位)阿里Java記憶體溢位
- JavaScript之記憶體溢位和記憶體洩漏JavaScript記憶體溢位
- [Java基礎]記憶體洩漏和記憶體溢位Java記憶體溢位
- JAVA記憶體區域與記憶體溢位異常Java記憶體溢位
- 深入淺出JVM(十四)之記憶體溢位、洩漏與引用JVM記憶體溢位
- mybatis-plus getOne 記憶體溢位MyBatis記憶體溢位
- return new物件造成溢位記憶體物件記憶體
- Android記憶體溢位、記憶體洩漏常見案例分析及最佳實踐總結Android記憶體溢位
- java記憶體溢位和記憶體洩漏的區別Java記憶體溢位
- jvm記憶體設定及記憶體溢位、解決方案JVM記憶體溢位
- 【Java】 記憶體分配全面淺析Java記憶體
- Windbg下使用dump分析記憶體溢位記憶體溢位
- Redis 報”OutOfDirectMemoryError“(堆外記憶體溢位)RedisError記憶體溢位
- 關於 PHP 記憶體溢位的思考PHP記憶體溢位
- 記憶體和棧溢位問題定位記憶體
- php記憶體溢位了怎麼辦?PHP記憶體溢位
- Windows Tomcat 記憶體溢位解決方法WindowsTomcat記憶體溢位
- JVM(2)-Java記憶體區域與記憶體溢位異常JVMJava記憶體溢位
- Netty 中的記憶體分配淺析Netty記憶體
- 淺析java記憶體管理機制Java記憶體
- Java中字串記憶體位置淺析Java字串記憶體
- 【高併發】高併發環境下如何防止Tomcat記憶體溢位?看完我懂了!!Tomcat記憶體溢位
- BufferedImage記憶體洩漏和溢位問題記憶體
- 基礎學習-記憶體溢位問題記憶體溢位
- Executors使用不當引起的記憶體溢位記憶體溢位
- tomcat記憶體溢位:PermGen space解決方法Tomcat記憶體溢位
- 簡單的記憶體“洩露”和“溢位”記憶體
- vue專案編譯node記憶體溢位Vue編譯記憶體溢位
- 強如 Disruptor 也發生記憶體溢位?記憶體溢位
- JavaScript閉包(記憶體洩漏、溢位以及記憶體回收),超直白解析JavaScript記憶體
- 淺談Android記憶體優化Android記憶體優化
- 淺析Linux Kernel[5.11.0]記憶體管理(一)Linux記憶體