2016-08-25 23 views
3

このスレッドを起動すると、Androidアプリがクラッシュします。Java - メモリ割り当ての問題(GC_FOR_ALLOC)

このスレッドは、電話機を再起動する必要があります。私はそれを起動すると、それは、携帯電話を再起動しないと私はLOGに次のテキストを持っている:

8月25日09:12:00.946 26029から26813/com.datasulting.chris.smsgateway D/dalvikvm :GC_FOR_ALLOCは、1279K(30823)を解放し、4485K/9968K、 を一時停止しました。53ms、合計53ms 08-25 09:12:01.294 26029-26813/com.datasulting.chris.smsgateway D/dalvikvm: 前GC割り当て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 .datavulting.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、53msは合計 08-25 09:12:02.901 26029-26813/com.datasulting.chris.smsgateway D/dalvikvm:前回のGC割り当て1279K 08285 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:1280K

前回のGCのallocの間でこれが私のスレッドです。

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

このコードには多くの問題があります。

主な問題 - あなたのスレッドは「アクティブ」な状態で待機しています。これはつまり、各繰り返しの新しいCalendarオブジェクトをループして作成することです。その後すぐにそのオブジェクトを捨て、新しいオブジェクトを作成します。

ガベージコレクタがコードに苦労していることに驚いていますか?私の気まぐれが人々に問題を理解させることを妨げないことを確実にするために、ガベージオブジェクトだけを作成する「ホット」ループを可能にする世界のガベージコレクタは設計されていません。特に「モバイル」の世界では、

したがって、明らかな答え:スレッドを追加してください。あなたのループの本体でsleep()ステートメント。以下のような:リブート

  • なしの場合:
  • 繰り返し
  • あなたのコードはありません分間のスリープ:

    • チェックは、その時間は
    • そうであれば再起動した場合 - かどうかを確認します再起動の時間 - はいの場合:リブート - リピート

      次に、sあなたの(ごめん)恐ろしいコードの青梅の一般的なフィードバック:

      • は、あなたがそれらを比較するために、フランス語の文字列にして平日に回すことが絶対夢中です。あなたはすでに月曜日に0と書いてあるintを持っています。次に、週の日のカレンダーオブジェクトにintとして問い合わせます。 0を "Lundi"に変換しているので、0を "Lundi"に再度変換して文字列を一致させることができます。クレイジーです
      • あなたの名前はひどいです。本当に1つの言語に固執する。私は "checkRebootQuo"は "毎時再起動"についてだと思います。 「checkRebootHeb」は何とか毎週リブートします。変数を "rebootHourly"と "rebootWeekly"のどちらに変更するかは、はるかに明確になります。
      • 最後に、複数のブール値パラメータを使用してメソッド内に複数のIFを使用しないでください。代わりに、多態性を使用します。ループして再起動することを知っている基本クラスを持つ。次に2つのサブクラスがあります。次の1時間に再起動する方法を知っている人と、指定した曜日に再起動する人がいます。
    +0

    ありがとう、しかし、私は問題を解決するとは思わない。このスレッドは1週間に実行されることがあります。私はこの解決策が問題を解決すると思いますが、ただちに解決します。 –

    +0

    おそらく、毎分**数百万のオブジェクトを作成しているため、メモリの問題が発生しています。あなたは常にGCを粉々にしています。スリーピングを追加すると、新しいオブジェクトの数が1分に1つに減らされます。それを知っていますか? – GhostCat

    +0

    オクラメン私は提案に感謝を参照してください! –