Java - 内存分配困难(GC_FOR_ALLOC)

标签 java android multithreading

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

这个线程应该重启手机。当我启动它时,它不会重新启动手机,并且我在日志中有以下文本:

08-25 09:12:00.946 26029-26813/com.datasulting.chris.smsgateway D/dalvikvm: GC_FOR_ALLOC freed 1279K (30823), 55% free 4485K/9968K, paused 53ms, total 53ms 08-25 09:12:01.294 26029-26813/com.datasulting.chris.smsgateway D/dalvikvm: between the previous GC alloc 1280K 08-25 09:12:01.346 26029-26813/com.datasulting.chris.smsgateway D/dalvikvm: GC_FOR_ALLOC freed 1280K (30820), 55% free 4485K/9968K, paused 52ms, total 52ms 08-25 09:12:01.713 26029-26813/com.datasulting.chris.smsgateway D/dalvikvm: between the previous GC alloc 1279K 08-25 09:12:01.768 26029-26813/com.datasulting.chris.smsgateway D/dalvikvm: GC_FOR_ALLOC freed 1279K (30813), 55% free 4486K/9968K, paused 55ms, total 55ms 08-25 09:12:02.111 26029-26813/com.datasulting.chris.smsgateway D/dalvikvm: between the previous GC alloc 1279K 08-25 09:12:02.164 26029-26813/com.datasulting.chris.smsgateway D/dalvikvm: GC_FOR_ALLOC freed 1280K (30819), 55% free 4486K/9968K, paused 53ms, total 53ms 08-25 09:12:02.504 26029-26813/com.datasulting.chris.smsgateway D/dalvikvm: between the previous GC alloc 1279K 08-25 09:12:02.557 26029-26813/com.datasulting.chris.smsgateway D/dalvikvm: GC_FOR_ALLOC freed 1280K (30823), 55% free 4485K/9968K, paused 53ms, total 53ms 08-25 09:12:02.901 26029-26813/com.datasulting.chris.smsgateway D/dalvikvm: between the previous GC alloc 1279K 08-25 09:12:02.956 26029-26813/com.datasulting.chris.smsgateway D/dalvikvm: GC_FOR_ALLOC freed 1279K (30818), 55% free 4485K/9968K, paused 55ms, total 55ms 08-25 09:12:03.298 26029-26813/com.datasulting.chris.smsgateway D/dalvikvm: between the previous 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;
    }
}

最佳答案

该代码有很多问题。

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

您对垃圾收集器难以处理您的代码感到惊讶吗?只是为了确保我的讽刺不会阻止人们理解这个问题:世界上没有垃圾收集器被设计为允许只创建垃圾对象的“热”循环;特别是在“移动”世界中。

所以,显而易见的答案是:在循环体中添加一些 Thread.sleep() 语句;喜欢:

  • 检查是否到了重新启动的时间
  • 如果是:重启
  • 如果没有:睡一分钟
  • 重复

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

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

  • 为了比较它们而将工作日转换为法语字符串绝对是疯狂的。你已经有一个 int 表示星期一为 0。然后只需将星期几的日历对象作为 int 询问即可。您正在将 0 转换为“Lundi”,以便您可以再次将 0 转换为“Lundi”以进行字符串匹配。太疯狂了。
  • 你的命名也很糟糕。真的 - 坚持使用一种语言。我猜“checkRebootQuo”是关于“每小时重启”;而“checkRebootHeb”是关于每周以某种方式重新启动。如果您将变量重命名为“rebo​​otHourly”与“rebo​​otWeekly”……那会更清楚。
  • 最后:不要使用多个 boolean 参数,然后在您的方法中有多个 IF。相反:使用多态性。有知道循环和重启的基类;然后有两个子类;一个知道如何在下一个小时重新启动,另一个知道如何在一周中的指定日期重新启动。

关于Java - 内存分配困难(GC_FOR_ALLOC),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39138913/

相关文章:

java - Detection of Loops in Java Bytecode - 区分后端类型

java - 如何使用 Socket.IO-client Java 将 String 消息从 Android 发送到服务器?

c++ - Boost tread 代码在 VC++ 下编译但在 GCC 下不编译 : how to get better debug info

multithreading - F# Winforms 图表异步更新

java - 如何在java中处理阿拉伯语

java - 在java中反转字符串模式

联合两个字符串的 Java String 实用程序/方法

android - Handler.dispatchMessage(msg) 和 Handler.sendMessage(msg) 的区别

android - 启动应用程序时出现内部错误

java - 现代 JVM 中的双重检查锁定