简体   繁体   中英

Java - Memory Allocation Difficulties (GC_FOR_ALLOC)

My Android app crash when I start this Thread.

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 :

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

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 . 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; 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. Then just ask the calendar object for the week day as int. You are converting 0 to "Lundi" so that you can convert 0 to "Lundi" again to make a string match. Crazy that is.
  • Your naming is terrible, too. Really - stick with one language. I guess "checkRebootQuo" is about "hourly rebooting"; whereas "checkRebootHeb" is about weekly reboots somehow. If you would rename your variables to "rebootHourly" vs "rebootWeekly" ... that would be much clearer.
  • Finally: dont use multiple boolean parameters to then have multiple IFs in your methods. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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