Java-内存分配困难(GC_FOR_ALLOC)

Java-内存分配困难(GC_FOR_ALLOC),java,android,multithreading,Java,Android,Multithreading,启动此线程时,我的Android应用程序崩溃 此线程应重新启动手机。当我启动它时,它不会重新启动手机,我的日志中有以下文字: 08-25 09:12:00.946 26029-26813/com.datasulting.chris.smsgateway D/dalvikvm:GC-FOR-ALLOC释放1279K(30823),55%释放4485K/9968K, 暂停53毫秒,总计53毫秒08-25 09:12:01.294 26029-26813/com.datasulting.chris.s

启动此线程时,我的Android应用程序崩溃

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

08-25 09:12:00.946 26029-26813/com.datasulting.chris.smsgateway D/dalvikvm:GC-FOR-ALLOC释放1279K(30823),55%释放4485K/9968K, 暂停53毫秒,总计53毫秒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\u FOR\u 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\u FOR\u 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\u FOR\u ALLOC 释放1280K(30819),55%释放4486K/9968K,暂停53毫秒,总计53毫秒 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\u FOR\u ALLOC 释放1280K(30823),55%释放4485K/9968K,暂停53毫秒,总计53毫秒 08-25 09:12:02.901 26029-26813/com.datasulting.chris.smsgateway D/dalvikvm:在上一次GC分配之间1279K 08-25 09:12:02.956 26029-26813/com.datasulting.chris.smsgateway D/dalvikvm:GC\u FOR\u ALLOC 释放1279K(30818),55%释放4485K/9968K,暂停55ms,总计55ms 08-25 09:12:03.298 26029-26813/com.datasulting.chris.smsgateway D/dalvikvm:在先前的GC分配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;
    }
}

这个代码有很多错误

您的主要问题-您的线程正在进行“活动”等待。这意味着:它只是在每次迭代中循环并创建一个新的日历对象。然后立即扔掉该对象,并创建一个新对象

垃圾收集器很难处理您的代码,您对此感到惊讶吗?为了确保我的讽刺不会妨碍人们理解这个问题:世界上没有一个垃圾收集器被设计成只允许创建垃圾对象的“热”循环;尤其是在“移动”世界

因此,显而易见的答案是:在循环体中添加一些Thread.sleep()语句;比如:

  • 检查是否是重新启动的时间
  • 如果是:重新启动
  • 如果没有:睡一分钟
  • 重复
您的代码执行以下操作: -检查是否是重新启动的时间 -如果是:重新启动 -重复

然后,对您(抱歉)的糟糕代码给出一些一般性反馈:

  • 为了比较它们,你把工作日变成了法文字符串,这绝对是疯狂的。你已经得到一个整数,表示星期一为0。然后只需将日历对象的星期日设为int。您正在将0转换为“Lundi”,以便可以再次将0转换为“Lundi”,以使字符串匹配。这太疯狂了
  • 你的名字也很糟糕。真的-坚持使用一种语言。我猜“checkRebootQuo”是关于“每小时重新启动”;而“checkRebootHeb”是关于每周重新启动的。如果您将变量重命名为“ReboTourly”与“ReboToWeekly”。。。这将更加清楚
  • 最后:不要使用多个布尔参数,然后在方法中使用多个IFs。相反:使用多态性。具有知道循环和重新启动的基类;然后有两个子类;一个知道如何在下一个小时重新启动,另一个知道如何在一周中的指定日期重新启动

非常感谢并为我的英语感到抱歉:谢谢,但我认为这不能解决问题。此线程有时会运行一周。我认为这个解决方案可以解决这个问题,但只是暂时的。你正在遇到内存问题,因为你可能每分钟创建数百万个对象。您不断地搅动GC。添加睡眠时,新对象的数量将减少到每分钟一个。你知道我明白了吗?