1. 程式人生 > >Android常見異常解決方法

Android常見異常解決方法

1,Unable to execute dex: Multiple dex files define 解決方法

問題發生概述:
  將android程式複製執行時,報錯Unable to execute dex: Multiple dex files define;Conversion to Dalvik format failed: Unable to execute dex: Multiple dex files define Lcom/kenai/jbosh/AbstractAttr;

具體解決方案如下:

方法一:
  Eclipse->Project->去掉Build Automatically->Clear ->Build Project->Build Automatically,關閉Eclipse,再開啟(我的問題不是出在這)


方法二:           
  更新ADT外掛,刪除workspace目錄下的.metadata目錄,(這個解決方案沒有嘗試,因為在開發過程中,我只是更換了一個jar包而出現的錯誤,而且開發環境不能連網路,不方便嘗試)


方法三:
  在你的專案下某個資料夾中有一個字尾為*.APK的檔案,刪掉,重啟Eclipse即可。

方法四:
  原因是有重複的。jar被引用,可以檢視你的build path,尤其是Android Dependencies一定有重複引入的.jar包,解決的方法是在libs刪除重複的jar即可。 (我的解決方法)


方法五:
  在專案中,有一個類的包名和引用的jar包中的類和包名一致,我用的是jar包中的類,所以工程中的這個類就是重複引用的,刪除工程中重複引用的類後,成功打包啟動。希望各位同學注意這個小問題

deadObjectException異常,說明應用的service已經停止,要麼是從作業系統中喪生,要麼從應用程式中終止。

這種情況,測試暫時只會發生在魅族2 手機上,下面這篇文章從程式碼層除錯進行了改動,

http://blog.csdn.net/casun_li/article/details/8966565 

我由於用的是別人的sdk所以沒有辦法改原始碼,於是求助大牛,用到了以下方法輕鬆解決了

<application

        android:hardwareAccelerated="false"  .....

也就是在application標籤裡面添加了一句android:hardwareAccelerated="false" (禁用硬體加速)

於是問題就解決了,

 開始的時候我是加到了對應的activity,標籤裡面,結果發現第一次可以執行完美等一段時間又會出現這個問題,

改了application,android:hardwareAccelerated="false"於是就好了,

這個問題真是蛋疼,,,不過,希望還有好的解決辦法有人分享一下,硬體加速的問題,影響遊戲效能

lr vuser過大時,程式報錯。java.lang.OutOfMemoryError: unable to create new native thread

百度一下,我就知道 =-----------------------------------------------------------------------------------= 這個異常問題本質原因是我們建立了太多的執行緒,而能建立的執行緒數是有限制的,導致了異常的發生。能建立的執行緒數的具體計算公式如下:  (MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) = Number of threads MaxProcessMemory 指的是一個程序的最大記憶體 JVMMemory         JVM記憶體 ReservedOsMemory  保留的作業系統記憶體 ThreadStackSize      執行緒棧的大小 在java語言裡, 當你建立一個執行緒的時候,虛擬機器會在JVM記憶體建立一個Thread物件同時建立一個作業系統執行緒,而這個系統執行緒的記憶體用的不是JVMMemory,而是系統中剩下的記憶體(MaxProcessMemory - JVMMemory - ReservedOsMemory)。 由公式得出結論:你給JVM記憶體越多,那麼你能建立的執行緒越少,越容易發生java.lang.OutOfMemoryError: unable to create new native thread。 解決問題:  1、如果程式中有bug,導致建立大量不需要的執行緒或者執行緒沒有及時回收,那麼必須解決這個bug,修改引數是不能解決問題的。 2、如果程式確實需要大量的執行緒,現有的設定不能達到要求,那麼可以通過修改MaxProcessMemory,JVMMemory,ThreadStackSize這三個因素,來增加能建立的執行緒數: a, MaxProcessMemory 使用64位作業系統 b, JVMMemory   減少JVMMemory的分配    使用tomcat的catalina.bat這裡配置,下面有解析。set JAVA_OPTS=-Xms1024m -Xmx1024m -XX:PermSize=256M -XX:MaxNewSize=512m -XX:MaxPermSize=256m -XX:SurvivorRatio=6 c, ThreadStackSize  減小單個執行緒的棧大小 分析: MaxProcessMemory程序最大的定址空間,但我想這個值應該也不會超過虛擬記憶體和實體記憶體的總和吧。關於不同系統的程序可定址的最大空間,可參考下面表格:

Maximum Address Space Per Process

Operating System

Maximum Address Space Per Process

Redhat Linux 32 bit

2 GB

Redhat Linux 64 bit

3 GB

Windows 98/2000/NT/Me/XP

2 GB

Solaris x86 (32 bit)

4 GB

Solaris 32 bit

4 GB

Solaris 64 bit

Terabytes

JVMMemory: Heap + PermGen

ReservedOSMemory:Native heap,JNI

在2000/XP/2003的boot.ini裡頭有一個啟動選項,好像是:/PAE /3G ,可以讓使用者程序最大記憶體擴充至3G,這時作業系統只能佔用最多1G的虛存。那樣應該可以讓JVM建立更多的執行緒。

--------------------解決方案--------------------------

JVM堆大小的調整   Sun HotSpot 1.4.1使用分代收集器,它把堆分為三個主要的域:新域、舊域以及永久域。Jvm生成的所有新物件放在新域中。一旦物件經歷了一定數量的垃圾收集迴圈後,便獲得使用期並進入舊域。在永久域中jvm則儲存class和method物件。就配置而言,永久域是一個獨立域並且不認為是堆的一部分。   下面介紹如何控制這些域的大小。可使用-Xms和-Xmx 控制整個堆的原始大小或最大值。   下面的命令是把初始大小設定為128M:   java –Xms128m   –Xmx256m為控制新域的大小,可使用-XX:NewRatio設定新域在堆中所佔的比例。   下面的命令把整個堆設定成128m,新域比率設定成3,即新域與舊域比例為1:3,新域為堆的1/4或32M: java –Xms128m –Xmx128m –XX:NewRatio =3可使用-XX:NewSize和-XX:MaxNewsize設定新域的初始值和最大值。   下面的命令把新域的初始值和最大值設定成64m: java –Xms256m –Xmx256m –Xmn64m   永久域預設大小為4m。執行程式時,jvm會調整永久域的大小以滿足需要。每次調整時,jvm會對堆進行一次完全的垃圾收集。   使用-XX:MaxPerSize標誌來增加永久域搭大小。在WebLogic Server應用程式載入較多類時,經常需要增加永久域的最大值。當jvm載入類時,永久域中的物件急劇增加,從而使jvm不斷調整永久域大小。為了避免調整,可使用-XX:PerSize標誌設定初始值。   下面把永久域初始值設定成32m,最大值設定成64m。 java -Xms512m -Xmx512m -Xmn128m -XX:PermSize=32m -XX:MaxPermSize=64m   預設狀態下,HotSpot在新域中使用複製收集器。該域一般分為三個部分。第一部分為Eden,用於生成新的物件。另兩部分稱為救助空間,當Eden充滿時,收集器停止應用程式,把所有可到達物件複製到當前的from救助空間,一旦當前的from救助空間充滿,收集器則把可到達物件複製到當前的to救助空間。From和to救助空間互換角色。維持活動的物件將在救助空間不斷複製,直到它們獲得使用期並轉入舊域。使用-XX:SurvivorRatio可控制新域子空間的大小。   同NewRation一樣,SurvivorRation規定某救助域與Eden空間的比值。比如,以下命令把新域設定成64m,Eden佔32m,每個救助域各佔16m: java -Xms256m -Xmx256m -Xmn64m -XX:SurvivorRation =2   如前所述,預設狀態下HotSpot對新域使用複製收集器,對舊域使用標記-清除-壓縮收集器。在新域中使用複製收集器有很多意義,因為應用程式生成的大部分物件是短壽命的。理想狀態下,所有過渡物件在移出Eden空間時將被收集。如果能夠這樣的話,並且移出Eden空間的物件是長壽命的,那麼理論上可以立即把它們移進舊域,避免在救助空間反覆複製。但是,應用程式不能適合這種理想狀態,因為它們有一小部分中長壽命的物件。最好是保持這些中長壽命的物件並放在新域中,因為複製小部分的物件總比壓縮舊域廉價。為控制新域中物件的複製,可用-XX:TargetSurvivorRatio控制救助空間的比例(該值是設定救助空間的使用比例。如救助空間位1M,該值50表示可用500K)。該值是一個百分比,預設值是50。當較大的堆疊使用較低的sruvivorratio時,應增加該值到80至90,以更好利用救助空間。用-XX:maxtenuring threshold可控制上限。   為放置所有的複製全部發生以及希望物件從eden擴充套件到舊域,可以把MaxTenuring Threshold設定成0。設定完成後,實際上就不再使用救助空間了,因此應把SurvivorRatio設成最大值以最大化Eden空間,設定如下: java … -XX:MaxTenuringThreshold=0 –XX:SurvivorRatio=50000 … 垃圾回收描述: 垃圾回收分多級,0級為全部(Full)的垃圾回收,會回收OLD段中的垃圾;1級或以上為部分垃圾回收,只會回收Young中的垃圾,記憶體溢位通常發生於OLD段或Perm段垃圾回收後,仍然無記憶體空間容納新的Java物件的情況。 當一個URL被訪問時,記憶體申請過程如下: A. JVM會試圖為相關Java物件在Eden中初始化一塊記憶體區域 B. 當Eden空間足夠時,記憶體申請結束。否則到下一步 C. JVM試圖釋放在Eden中所有不活躍的物件(這屬於1或更高階的垃圾回收);釋放後若Eden空間仍然不足以放入新物件,則試圖將部分Eden中活躍物件放入Survivor區/OLD區 D. Survivor區被用來作為Eden及OLD的中間交換區域,當OLD區空間足夠時,Survivor區的物件會被移到Old區,否則會被保留在Survivor區 E. 當OLD區空間不夠時,JVM會在OLD區進行完全的垃圾收集(0級) F. 完全垃圾收集後,若Survivor及OLD區仍然無法存放從Eden複製過來的部分物件,導致JVM無法在Eden區為新物件建立記憶體區域,則出現”out of memory錯誤” Java堆相關引數: ms/mx:定義YOUNG+OLD段的總尺寸,ms為JVM啟動時YOUNG+OLD的記憶體大小;mx為最大可佔用的YOUNG+OLD記憶體大小。在使用者生產環境上一般將這兩個值設為相同,以減少執行期間系統在記憶體申請上所花的開銷。 NewSize/MaxNewSize:定義YOUNG段的尺寸,NewSize為JVM啟動時YOUNG的記憶體大小;MaxNewSize為最大可佔用的YOUNG記憶體大小。在使用者生產環境上一般將這兩個值設為相同,以減少執行期間系統在記憶體申請上所花的開銷。 PermSize/MaxPermSize:定義Perm段的尺寸,PermSize為JVM啟動時Perm的記憶體大小;MaxPermSize為最大可佔用的Perm記憶體大小。在使用者生產環境上一般將這兩個值設為相同,以減少執行期間系統在記憶體申請上所花的開銷。 SurvivorRatio:設定Survivor空間和Eden空間的比例 例: MEM_ARGS="-Xms512m -Xmx512m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:PermSize=128m - XX:MaxPermSize=128m -XX:SurvivorRatio=6" 在上面的例子中: YOUNG+OLD: 512M YOUNG: 256M Perm: 128M Eden: YOUNG*6/(6+1+1)=192M Survivor: YOUNG/(6+1+1)=32M Java堆的總尺寸(JVMMemory)=YOUNG+OLD+Perm=640M ------------解決方法2:減小單個執行緒的棧大小---------
引數名稱 含義 預設值
-Xms 初始堆大小 實體記憶體的1/64(<1GB) 預設(MinHeapFreeRatio引數可以調整)空餘堆記憶體小於40%時,JVM就會增大堆直到-Xmx的最大限制.
-Xmx 最大堆大小 實體記憶體的1/4(<1GB) 預設(MaxHeapFreeRatio引數可以調整)空餘堆記憶體大於70%時,JVM會減少堆直到 -Xms的最小限制
-Xmn 年輕代大小(1.4or lator)
注意:此處的大小是(eden+ 2 survivor space).與jmap -heap中顯示的New gen是不同的。
整個堆大小=年輕代大小 + 年老代大小 + 持久代大小.
增大年輕代後,將會減小年老代大小.此值對系統性能影響較大,Sun官方推薦配置為整個堆的3/8
-XX:NewSize 設定年輕代大小(for 1.3/1.4)
-XX:MaxNewSize 年輕代最大值(for 1.3/1.4)
-XX:PermSize 設定持久代(perm gen)初始值 實體記憶體的1/64
-XX:MaxPermSize 設定持久代最大值 實體記憶體的1/4
-Xss 每個執行緒的堆疊大小 JDK5.0以後每個執行緒堆疊大小為1M,以前每個執行緒堆疊大小為256K.更具應用的執行緒所需記憶體大小進行 調整.在相同實體記憶體下,減小這個值能生成更多的執行緒.但是作業系統對一個程序內的執行緒數還是有限制的,不能無限生成,經驗值在3000~5000左右
一般小的應用, 如果棧不是很深, 應該是128k夠用的 大的應用建議使用256k。這個選項對效能影響比較大,需要嚴格的測試。(校長)
和threadstacksize選項解釋很類似,官方文件似乎沒有解釋,在論壇中有這樣一句話:"”
-Xss is translated in a VM flag named ThreadStackSize”
一般設定這個值就可以了。
-XX:ThreadStackSize Thread Stack Size (0 means use default stack size) [Sparc: 512; Solaris x86: 320 (was 256 prior in 5.0 and earlier); Sparc 64 bit: 1024; Linux amd64: 1024 (was 0 in 5.0 and earlier); all others 0.]
-XX:NewRatio 年輕代(包括Eden和兩個Survivor區)與年老代的比值(除去持久代) -XX:NewRatio=4表示年輕代與年老代所佔比值為1:4,年輕代佔整個堆疊的1/5
Xms=Xmx並且設定了Xmn的情況下,該引數不需要進行設定。
-XX:SurvivorRatio Eden區與Survivor區的大小比值 設定為8,則兩個Survivor區與一個Eden區的比值為2:8,一個Survivor區佔整個年輕代的1/10
-Xss(或-ss) 這個其實也是可以預設的,如果你真的覺得有設定的必要,你就改下吧,1.5以後是1M的預設大小(指一個執行緒的native空間),如果程式碼不多,可以設定小點來讓系統可以接受更大的記憶體。注意,還有一個引數是-XX:ThreadStackSize,這兩個引數在設定的過程中如果都設定是有衝突的,一般按照JVM常理來說,誰設定在後面,就以誰為主,但是最後發現如果是在1.6以上的版本,-Xss設定在後面的確都是以-Xss為主,但是要是-XX:ThreadStackSize設定在後面,主執行緒還是為-Xss為主,而其它執行緒以-XX:ThreadStackSize為主,主執行緒做了一個特殊判定處理;單獨設定都是以本身為主,-Xss不設定也不會採用其預設值,除非兩個都不設定會採用-Xss的預設值。