2016-08-25 65 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

好的,我看到我感谢您的建议! –