Java - 内存分配困难(GC_FOR_ALLOC)

时间:2016-08-25 07:13:55

标签: java android multithreading

启动此主题时,我的Android应用程序崩溃了。

此线程应该重启手机。当我启动它时,它不会重新启动手机,我在LOG中有以下文字:

  

08-25 09: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 alloc 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 alloc 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 alloc 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;
    }
}

1 个答案:

答案 0 :(得分:0)

该代码有很多问题。

你的主要问题 - 你的线程正在做什么"活跃"等候。这意味着:它只是循环并创建一个新的Calendar对象每次迭代。然后你立即扔掉那个物体,并创造一个新物体。

你很惊讶垃圾收集器很难用你的代码吗?而且只是为了确保我的讽刺并不能阻止人们理解这个问题:世界上没有任何垃圾收集器能够让人们感受到热情的问题。只创建垃圾对象的循环;尤其是在" mobile"世界。

所以,明显的答案是:在循环体中添加一些Thread.sleep()语句;像:

  • 检查是否是重启的小时
  • 如果是:重启
  • 如果不是:睡了一分钟
  • 重复

您的代码有:   - 检查是否重启的时间   - 如果是:重启   - 重复

然后,对你(遗憾的)可怕代码的一些一般性反馈:

  • 为了比较它们,你将工作日转换为法语字符串是绝对疯狂的。你已经有了一个在星期一说0的int。然后只需将日历对象的工作日视为int。您正在将0转换为" Lundi"这样你就可以将0转换为" Lundi"再次进行字符串匹配。疯了就是。
  • 你的命名也很可怕。真的 - 坚持用一种语言。我想" checkRebootQuo"是关于"每小时重启&#34 ;;而" checkRebootHeb"是以某种方式每周重新开始。如果要将变量重命名为" rebootHourly" vs" rebootWeekly" ......那会更清楚。
  • 最后:不要使用多个布尔参数,然后在方法中使用多个IF。相反:使用多态。有知道循环和重启的基类;然后有两个子类;一个知道如何在下一个小时重新启动,另一个在一周的指定日重新启动。