简体   繁体   English

Java - 内存分配困难(GC_FOR_ALLOC)

[英]Java - Memory Allocation Difficulties (GC_FOR_ALLOC)

My Android app crash when I start this Thread. 当我启动此线程时,我的Android应用程序崩溃。

This Thread should restart the phone. 这个线程应该重启手机。 When I start it it don't restart the phone and I have the following text in the LOG : 当我启动它时,它不会重新启动手机,我在LOG中有以下文字:

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.datas 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之间分配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.datas ulting.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 ulting.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之间分配1280K

This is my Thread. 这是我的主题。

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;
    }
}

Lots of things wrong with that code. 这段代码有很多问题。

Your main problem - your thread is doing "active" waiting. 你的主要问题 - 你的线程在做“主动”等待。 This means: it just loops and creates a new Calendar object each iteration . 这意味着:它只是循环并在每次迭代时创建一个新的Calendar对象。 Then you immediately throw away that object, and create a new one. 然后你立即扔掉那个物体,并创造一个新物体。

And you are surprised that the garbage collector has a hard time with your code? 而且你很惊讶垃圾收集器很难用你的代码? And just to be sure that my sarcasm doesn't prevent people from understanding the issue: no garbage collector in the world is designed to allow for a "hot" loop that only creates garbage objects; 并且只是为了确保我的讽刺并不妨碍人们理解这个问题:世界上没有垃圾收集器被设计为允许仅产生垃圾对象的“热”循环; especially in the "mobile" world. 特别是在“移动”世界。

So, the obvious answer: add some Thread.sleep() statement in the body of your loop; 所以,明显的答案是:在循环体中添加一些Thread.sleep()语句; like: 喜欢:

  • check if its the hour to reboot 检查是否重启的时间
  • if yes: reboot 如果是:重启
  • if no: sleep for a minute 如果不是:睡一分钟
  • repeat 重复

Your code does: - check if its the hour to reboot - if yes: reboot - repeat 你的代码确实: - 检查它是否需要重启的时间 - 如果是:重启 - 重复

Then, some general feedback on your (sorry) horrible code: 然后,对你(遗憾的)可怕代码的一些一般性反馈:

  • It is absolutely crazy that you turn weekdays in to french strings in order to compare them. 你把工作日变成法国字符串以便比较它们是绝对疯狂的。 You already got an int that says 0 for Monday. 你已经有了一个在星期一说0的int。 Then just ask the calendar object for the week day as int. 然后只需将日历对象的工作日视为int。 You are converting 0 to "Lundi" so that you can convert 0 to "Lundi" again to make a string match. 您将0转换为“Lundi”,以便您可以再次将0转换为“Lundi”以进行字符串匹配。 Crazy that is. 疯了就是。
  • Your naming is terrible, too. 你的命名也很可怕。 Really - stick with one language. 真的 - 坚持用一种语言。 I guess "checkRebootQuo" is about "hourly rebooting"; 我猜“checkRebootQuo”是关于“每小时重启”; whereas "checkRebootHeb" is about weekly reboots somehow. 而“checkRebootHeb”则是每周以某种方式重新启动。 If you would rename your variables to "rebootHourly" vs "rebootWeekly" ... that would be much clearer. 如果你将变量重命名为“rebo​​otHourly”vs“rebo​​otWeekly”......那将更加清晰。
  • Finally: dont use multiple boolean parameters to then have multiple IFs in your methods. 最后:不要使用多个布尔参数,然后在方法中使用多个IF。 Instead: use polymorphism. 相反:使用多态。 Have base class that knows to loop and reboot; 有知道循环和重启的基类; and then have two subclasses; 然后有两个子类; one that knows how to reboot on the next hour, and another one that reboots on the specified day of the week. 一个知道如何在下一个小时重新启动,另一个在一周的指定日重新启动。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM