2016-08-25 70 views
3

當我啓動此線程時,我的Android應用程序崩潰。Java - 內存分配困難(GC_FOR_ALLOC)

此線程應重新啓動手機。當我啓動它,它不重新啓動的手機和我在日誌中的以下文字:

9月8日至25日:12:00.946 26029-26813/com.datasulting.chris.smsgateway d/dalvikvm :GC_FOR_ALLOC已釋放1279K(30823),55%免費4485K/9968K, 暫停53ms,總計53ms 08-25 09:12:01.294 26029-26813/com.datasulting.chris.smsgateway D/dalvikvm:之前的 之前的GC alloc 1280K 08-25 09:12:01.346 26029-26813/com.datasulting.chris.smsgateway D/dalvikvm:GC_FOR_ALLOC 已釋放1280K(30820),55%免費4485K/9968K,暫停52ms,總計52ms 08-25 09:12:01.713 26029-26813/com.datasulting.chris.smsgateway D/dalvikvm:之前的GC分配1279K 08-25 09:12:01.768 26029-26813/com.datasulting.chris.smsgateway D/dalvikvm:GC_FOR_ALLOC 已釋放1279K(30813),55%免費4486K/9968K,暫停55ms,總共55ms 08-25 09:12:02.111 26029-26813/com.datasulting.chris.smsgateway D/dalvikvm:之前的GC分配1279K 08-25 09:12:02.164 26029-26813/com .datasulting.chris.smsgateway D/dalvikvm:GC_FOR_ALLOC 已釋放1280K(30819),55%免費4486K/9968K,暫停53ms,總計53ms 08-25 09:12:02.504 26029-26813/com.datasulting.chris.smsgateway D/dalvikvm:在以前的GC分配之間1279K 08-25 09:12:02.557 26029-26813/com.datasulting.chris.smsgateway D/dalvikvm:GC_FOR_ALLOC 釋放1280K(30823),55%免費4485K/9968K,暫停53ms,總計53ms 08-25 09:12:02.901 26029-26813/com.datasulting.chris.smsgateway D/dalvikvm:之前的GC alloc 1279K 08-25 09:12:02.956 26029-26813/com.datasulting.chris.smsgateway D/dalvikvm:GC_FOR_ALLOC 已釋放1279K(30818),55%免費4485K/9968K,暫停55ms,共55ms 08-25 09: 12:03.298 26029-26813/com.datasulting.chris.smsgateway d/dalvikvm:以前的GC ALLOC 1280K

之間

這是我的主題。

class Reboot implements Runnable { 

    private volatile boolean cancelled; 
    Boolean checkRebootHeb; 
    Boolean checkRebootQuo; 
    int jourDemandeeInt; 
    String jourDemandeeString; 
    String weekDay; 
    int dayOfWeek; 
    SimpleDateFormat df; 
    String heure; 
    String dayOfWeekString; 
    String heureDemandee; 
    Calendar c; 

    public Reboot(Boolean VARcheckReboot, Boolean VARcheckRebootQuo, int VARjour, String VARtextReboot) { 
     checkRebootHeb = VARcheckReboot; 
     checkRebootQuo = VARcheckRebootQuo; 
     jourDemandeeInt = VARjour; 
     heureDemandee = VARtextReboot; 
    } 


    @Override 
    public void run() { 

     while (!cancelled) { 

      if (jourDemandeeInt == 0){ 
       jourDemandeeString = "Lundi"; 
      } 
      if (jourDemandeeInt == 1){ 
       jourDemandeeString = "Mardi"; 
      } 
      if (jourDemandeeInt == 2){ 
       jourDemandeeString = "Mercredi"; 
      } 
      if (jourDemandeeInt == 3){ 
       jourDemandeeString = "Jeudi"; 
      } 
      if (jourDemandeeInt == 4){ 
       jourDemandeeString = "Vendredi"; 
      } 
      if (jourDemandeeInt == 5){ 
       jourDemandeeString = "Samedi"; 
      } 
      if (jourDemandeeInt == 6){ 
       jourDemandeeString = "Dimanche"; 
      } 

      c = Calendar.getInstance(); 
      dayOfWeek = c.get(Calendar.DAY_OF_WEEK); 
      df = new SimpleDateFormat("HH:mm"); 
      heure = df.format(c.getTime()); 


      if (Calendar.MONDAY == dayOfWeek) weekDay = "Lundi"; 
      else if (Calendar.TUESDAY == dayOfWeek) weekDay = "Mardi"; 
      else if (Calendar.WEDNESDAY == dayOfWeek) weekDay = "Mercredi"; 
      else if (Calendar.THURSDAY == dayOfWeek) weekDay = "Jeudi"; 
      else if (Calendar.FRIDAY == dayOfWeek) weekDay = "Vendredi"; 
      else if (Calendar.SATURDAY == dayOfWeek) weekDay = "Samedi"; 
      else if (Calendar.SUNDAY == dayOfWeek) weekDay = "Dimanche"; 


      dayOfWeekString = String.valueOf(dayOfWeek); 

      if (checkRebootQuo == true) { 
       if (heure.equals(heureDemandee)) { 
        try { 

         Process proc = Runtime.getRuntime().exec(new String[]{"su", "-c", "reboot"}); 
         proc.waitFor(); 
        } catch (Exception ex) { 
         ex.printStackTrace(); 
        } 
       } 
      } 

      if (checkRebootHeb == true) { 
       if (dayOfWeekString.equals(jourDemandeeString)) { 
        if (heure.equals(heureDemandee)) { 
         try { 

          Process proc = Runtime.getRuntime().exec(new String[]{"su", "-c", "reboot"}); 
          proc.waitFor(); 
         } catch (Exception ex) { 
          ex.printStackTrace(); 
         } 
        } 
       } 
      } 

     } 


    } 

    public void cancel() { 
     cancelled = true; 
    } 
} 
+0

非常感謝,對不起我的英文:p –

回答

0

該代碼有很多錯誤。

您的主要問題 - 您的線程正在做「主動」等待。這意味着:它只是循環並創建一個新的日曆對象每次迭代。然後你立即扔掉那個物體,並創建一個新的物體。

你感到驚訝的是垃圾收集器很難與你的代碼?只是爲了確定我的諷刺並不能阻止人們理解這個問題:世界上沒有垃圾收集器被設計爲允許「熱」循環,它只創建垃圾對象;特別是在「移動」世界。

所以,顯而易見的答案是:添加一些線程。sleep()語句在你的循環體中;像:

  • 檢查其小時重啓
  • 如果是:重啓
  • 如果沒有:睡一分鐘
  • 重複

你的代碼做: - 檢查其小時重新啓動 - 如果是:重啓 - 重複

然後,s ome對你的(對不起)可怕的代碼的一般反饋:

  • 它是絕對瘋狂的,你把平日法國字符串,以便比較它們。你已經得到了一個星期一爲0的整數。然後,只需要將星期幾的日曆對象作爲int。您正在將0轉換爲「Lundi」,以便您可以再次將0轉換爲「Lundi」以進行字符串匹配。瘋狂的是。
  • 你的命名也很糟糕。真的 - 堅持一種語言。我猜「checkRebootQuo」是關於「每小時重啓」的;而「checkRebootHeb」大約每週重啓一次。如果你想將你的變量重命名爲「rebo​​otHourly」vs「rebo​​otWeekly」......那會更清晰。
  • 最後:不要使用多個布爾參數,然後在你的方法中有多個IF。相反:使用多態。有知道循環和重新啓動的基類;然後有兩個亞類;一個知道如何在下一個小時重新啓動,另一個在一週的指定日期重新啓動。
+0

謝謝,但我不認爲它會解決問題。此線程有時會運行整整一週。我認爲這個解決方案將會解決這個問題,但只是暫時的。 –

+0

您正在運行內存問題,因爲您可能每分鐘創建**數百萬**個對象。你不斷攪動GC。當您添加睡眠時,您可以將每個新對象的數量減少到每分鐘一個。你知道嗎? – GhostCat

+0

好的,我看到我感謝您的建議! –