4

I am getting a No implementation found for native Ldalvik/system/VMRuntime;.pauseGc Error, below is the logCat.

05-13 22:39:22.538: W/dalvikvm(8350): No implementation found for native Ldalvik/system/VMRuntime;.pauseGc:(Ljava/lang/String;)I
05-13 22:39:22.543: E/MyThread(8350): Pause GC
05-13 22:39:22.543: E/MyThread(8350): java.lang.reflect.InvocationTargetException
05-13 22:39:22.543: E/MyThread(8350): at java.lang.reflect.Method.invokeNative(Native Method)
05-13 22:39:22.543: E/MyThread(8350): at java.lang.reflect.Method.invoke(Method.java:515)
05-13 22:39:22.543: E/MyThread(8350): at android.app.MyThread.pauseGC(MyThread.java:5525)
05-13 22:39:22.543: E/MyThread(8350): at android.app.MyThread.performLaunchActivity(MyThread.java:2324)
05-13 22:39:22.543: E/MyThread(8350): at android.app.MyThread.handleLaunchActivity(MyThread.java:2471)
05-13 22:39:22.543: E/MyThread(8350): at android.app.MyThread.access$900(MyThread.java:175)
05-13 22:39:22.543: E/MyThread(8350): at android.app.MyThread$H.handleMessage(MyThread.java:1308)
05-13 22:39:22.543: E/MyThread(8350): at android.os.Handler.dispatchMessage(Handler.java:102)
05-13 22:39:22.543: E/MyThread(8350): at android.os.Looper.loop(Looper.java:146)
05-13 22:39:22.543: E/MyThread(8350): at android.app.MyThread.main(MyThread.java:5602)
05-13 22:39:22.543: E/MyThread(8350): at java.lang.reflect.Method.invokeNative(Native Method)
05-13 22:39:22.543: E/MyThread(8350): at java.lang.reflect.Method.invoke(Method.java:515)
05-13 22:39:22.543: E/MyThread(8350): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
05-13 22:39:22.543: E/MyThread(8350): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
05-13 22:39:22.543: E/MyThread(8350): at dalvik.system.NativeStart.main(Native Method)
05-13 22:39:22.543: E/MyThread(8350): Caused by: java.lang.UnsatisfiedLinkError: Native method not found: dalvik.system.VMRuntime.pauseGc:(Ljava/lang/String;)I
05-13 22:39:22.543: E/MyThread(8350): at dalvik.system.VMRuntime.pauseGc(Native Method)
05-13 22:39:22.543: E/MyThread(8350): ... 15 more

I searched across various forums, but this bug is related to Samsung 4.4.2 and above updates for a Subset of note devices ( I have two Note devices with same specs and this bug only occurs on one of them)

The idea here is to know what is exactly causing this bug, so that I can change the course of my program to avoid a condition wherein this bug can occur. A credible or an official answer is most sought after and I am putting a bounty of 200 on this question once I get eligible.

In my case this occurs when I am doing a memory intense operation, my knowledge (Naive as it might be) tells me it has got something to do with pausing the GC, would a (manual) call to System.gc resolve things for me?

How to recover from this error? In my loop I am reading from One DB table, Address book and a file one after the other. These read values undergo calculation process and results are stored in a larger DB. These statements are in a while loop, I have put checks in try catch so that if any and not limited to this error occurs. I start from the next iteration of the loop using a continue statement in the catch clause- neglecting the record where crash occurs. However the execution is not guaranteed using this method, as the crash can keep happening forcing the subsequent records to be omitted.

Edit: here is the culprit block of code:

if(FLAG ==1){
    toRead=new File(getApplicationContext().getFilesDir()+"/Reminders/fileone.txt");
}else{
    toRead=new File(getApplicationContext().getFilesDir()+"/Reminders/output.txt");
}

//  copyDirectoryOneLocationToAnotherLocation(new File(getApplicationContext().getFilesDir()+"/Reminders/output.txt"), new File("mnt/sdcard/filecheck.txt"));


FileInputStream fis=new FileInputStream(toRead);
Scanner sc=new Scanner(fis);

String currentLine;
while(sc.hasNextLine()){
    try{
        System.out.println("count in file"+i);

        currentLine=sc.nextLine();
        // TODO = gets concatnated 
        StringTokenizer st=new StringTokenizer(currentLine,"=",false);
        CONTACT_NAME = toTitleCase(st.nextToken());


        if(CONTACT_NAME.contains("'")){
            CONTACT_NAME = CONTACT_NAME.replace("'", "");
        }
        // *********
        String listStr = st.nextToken();
        String cut = listStr.substring(1, listStr.length() - 1);
        String[] array = cut.split(",");

        //      System.out.println("Array is: "+Arrays.toString(array));


        CONTACT_ID = (array[0].trim());
        String dateStr = (array[1].trim());
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date date = format.parse(dateStr);
        java.sql.Date dx = new java.sql.Date(date.getTime());
        Date key = dx;
        dateToInsert = String.valueOf(dx); 

        CONTACT_IMAGE_URI = (array[2].trim());
        if(CONTACT_IMAGE_URI.contains("?typ")){
            CONTACT_IMAGE_URI = CONTACT_IMAGE_URI+"e=normal"; 
        }
        if (isCancelled()) {
            break;
        }
        progress = ("" + Character.toUpperCase(CONTACT_NAME.charAt(0)) + CONTACT_NAME.substring(1) + "\n"+i + " of " + lines + " Contacts"); // Progress displayed here. 
        years = getDiffYear(key);               // For years elapsed
        secon = seconds(key);                   // for seconds elapsed
        min = seconds(key) / 60;                // For minutes elapsed
        hours = getDiffHour(key);// For hours elapsed
        mon = months(String.valueOf(key));      // for months elapsed
        days = daysElapsed(key);                // Days elapsed
        weeks = daysElapsed(key) / 7;           // For weeks

        //===============================================================================================================
        if (dateToInsert.contains("0001-") == true){ //Special Case, we added 0001 to Birthdays Which Have NO Year field. 
            //===========================================================================================================

            dbHelper.insert(dateToInsert, CONTACT_NAME, "","", CONTACT_IMAGE_URI, "", "", "", CONTACT_ID, "", "","1"); // All other fields will be empty, because we don't have a Year. 
            int PRIMARY_ID = dbHelper.getPrimaryId();
            String FOREIGN_KEY = dbHelper.getHighestID(PRIMARY_ID); 


            //=====================================================================================================
            //In this case we are only interested in fetching the year alert for next birthday of this contact -->
            //=====================================================================================================

            intCal.yearsToNotify(years, dateToInsert); 
            int yearsSpecial = intCal.getYearsRegular();
            Date dateYearsReg = intCal.getYearsRegDate();

            dbHelper.insertNotifications(5, convertDate(dateYearsReg), 0, yearsSpecial,FOREIGN_KEY,PRIMARY_ID,CONTACT_IMAGE_URI,dateToInsert ); 

        }
        //=========================================================================
        //Case when all the Date fields exist and we set up notifications  --->
        //=========================================================================
        else if(dateToInsert != "null" && dateToInsert.contains("0001-") != true){
            dbHelper.insert(dateToInsert, CONTACT_NAME, String.valueOf(days), String.valueOf(hours), CONTACT_IMAGE_URI, String.valueOf(min),String.valueOf(mon), String.valueOf(secon), CONTACT_ID, String.valueOf(weeks), String.valueOf(years),"1");
            int PRIMARY_ID = dbHelper.getPrimaryId(); // Fetch the PrimaryId (_id) of the above inserted row, its the Foreign key for Notification and SpecialNotifications Table. 
            String FOREIGN_KEY = dbHelper.getHighestID(PRIMARY_ID); // Same as above, but fetches the Name field of the last inserted row. 



            //=========================================================================
            //**Database Insertions Notifications Table/ SpecialNotifications Table**
            //=========================================================================



            //=======================================================================================//
            //Regular intervals DB Insertions: 
            //======================================================================================//
            //Notification Types:
            //1 for months
            //2 for weeks
            //3 for days
            //4 for minutes
            //5 for years
            //6 for seconds
            //7 for hours
            //======================================================================================//

            //==============================
            //For Months 
            //==============================
            intCal.monthsNotify(mon, dateToInsert);
            int monSpecial =  intCal.getMonthRegular(); 
            Date dateMonReg = intCal.getMonRegDate(); 


            dbHelper.insertNotifications(1, convertDate(dateMonReg), 0, monSpecial,FOREIGN_KEY,PRIMARY_ID,CONTACT_IMAGE_URI,dateToInsert );


            //===============================
            //For Weeks 
            //===============================
            intCal.weeksToNotify(weeks,dateToInsert); 
            int weekSpecial = intCal.getWeekRegular();
            Date dateWeekReg =intCal.getWeekRegDate(); 

            dbHelper.insertNotifications(2, convertDate(dateWeekReg), 0, weekSpecial,FOREIGN_KEY,PRIMARY_ID,CONTACT_IMAGE_URI,dateToInsert );


            //===============================
            //For Days
            //===============================
            intCal.daysToNotify(days, dateToInsert); 
            int daysSpecial= intCal.getDaysRegular();  
            Date dateDaysReg = intCal.getDaysRegDate(); 
            dbHelper.insertNotifications(3, convertDate(dateDaysReg), 0, daysSpecial,FOREIGN_KEY,PRIMARY_ID,CONTACT_IMAGE_URI,dateToInsert );


            //===============================
            //For minutes
            //===============================
            intCal.minutesToNotify(min,dateToInsert);
            long minutesSpecial= intCal.getMinutesRegular();
            Date dateMinsReg = intCal.getMinutesRegDate(); 
            dbHelper.insertNotifications(4, convertDate(dateMinsReg), 0,(int) minutesSpecial,FOREIGN_KEY,PRIMARY_ID,CONTACT_IMAGE_URI,dateToInsert );
            //==============================
            //For Years
            //==============================
            intCal.yearsToNotify(years, dateToInsert); 
            int yearsSpecial = intCal.getYearsRegular();
            Date dateYearsReg = intCal.getYearsRegDate();
            dbHelper.insertNotifications(5, convertDate(dateYearsReg), 0, yearsSpecial,FOREIGN_KEY,PRIMARY_ID,CONTACT_IMAGE_URI,dateToInsert );
            //=============================
            //For Seconds
            //=============================
            intCal.secondsToNotify(secon, dateToInsert);
            long secondsSpecial= intCal.getSecondsRegular(); 
            Date dateSecondsReg = intCal.getSecondsRegDate(); 
            dbHelper.insertNotifications(6, convertDate(dateSecondsReg), 0, secondsSpecial,FOREIGN_KEY,PRIMARY_ID,CONTACT_IMAGE_URI,dateToInsert );


            //=============================
            //For Hours
            //=============================
            intCal.hoursToNotify(hours, dateToInsert); 
            int hoursSpecial= intCal.getHoursRegular();
            Date dateHoursReg= intCal.getHoursRegDate(); 
            dbHelper.insertNotifications(7, convertDate(dateHoursReg), 0, hoursSpecial,FOREIGN_KEY,PRIMARY_ID,CONTACT_IMAGE_URI,dateToInsert );



            //============================================================================================//
            //Special Intervals
            //============================================================================================//
            //Notification Types:
            //1 for months
            //2 for weeks
            //3 for days
            //4 for minutes
            //5 for years
            //6 for seconds
            //7 for hours
            //For Years


            intCal.specialIntervalYears(years, dateToInsert); 
            int yearsOnceSpecial =intCal.getYearsSpecial();
            Date dateYearsSpecial = intCal.getYearsSpDate(); 
            dbHelper.insertSpecialNotifications(5, convertDate(dateYearsSpecial), yearsOnceSpecial,FOREIGN_KEY,PRIMARY_ID);


            //For Months
            intCal.specialIntervalMonths(mon,dateToInsert); 
            int monthsOnceSpecial= intCal.getMonthsSpecial();
            Date dateMonthsSpecial = intCal.getMonthsSpDate();
            dbHelper.insertSpecialNotifications(1, convertDate(dateMonthsSpecial), monthsOnceSpecial,FOREIGN_KEY,PRIMARY_ID);


            //For Weeks
            intCal.specialIntervalsWeeks(weeks,dateToInsert); 
            int weeksOnceSpecial= intCal.getWeeksSpecial(); 
            Date dateWeeksSpecial = intCal.getWeeksSpDate(); 
            dbHelper.insertSpecialNotifications(2, convertDate(dateWeeksSpecial), weeksOnceSpecial,FOREIGN_KEY,PRIMARY_ID);

            //For Days
            intCal.specialIntervalsDays(days, dateToInsert); 
            int daysOnceSpecial= intCal.getDaysSpecial(); 
            Date dateDaysSpecial = intCal.getDaysSpDate(); 
            dbHelper.insertSpecialNotifications(3, convertDate(dateDaysSpecial), daysOnceSpecial,FOREIGN_KEY,PRIMARY_ID);

            //For Hours
            intCal.specialIntervalsHours(hours,dateToInsert); 
            int hoursOnceSpecial= intCal.getHoursSpecial();  
            Date dateHoursSpecial = intCal.getHoursSpDate(); 
            dbHelper.insertSpecialNotifications(7, convertDate(dateHoursSpecial), hoursOnceSpecial,FOREIGN_KEY,PRIMARY_ID);

            //For Minutes
            intCal.specialIntervalMinutes(min,dateToInsert); 
            long minutesOnceSpecial= intCal.getMinutesSpecial(); 
            Date dateMinutesSpecial= intCal.getMinutesSpDate(); 
            dbHelper.insertSpecialNotifications(4, convertDate(dateMinutesSpecial), (int)minutesOnceSpecial,FOREIGN_KEY,PRIMARY_ID);

            //For Seconds
            intCal.specialIntervalsSeconds(secon,dateToInsert); 
            long secondsOnceSpecial= intCal.getSecondsSpecial(); 
            Date dateSecondsSpecial= intCal.getSecondsSpDate(); 
            dbHelper.insertSpecialNotifications(6, convertDate(dateSecondsSpecial), secondsOnceSpecial,FOREIGN_KEY,PRIMARY_ID); 
        }

        publishProgress(progress);
        Asycdialog.setMax(lines);
        Asycdialog.incrementProgressBy(1);
        i++;
    }catch (Exception e){
        System.out.println("From catch 4"+e);
        continue; 
    }
}

Edit 2:

I am doing the above process inside a try catch wherein I am using transactions to speed up things. I have implemented these transaction snippets at the opening of the try block, where I start the transaction and I end them at the finally block and set them successful at the same place.

Skynet
  • 7,820
  • 5
  • 44
  • 80
  • I need a little more information here. 1. Can you reproduce the error regularly and in the same place? 2. Are you able to use a Step Through in that case to find the offending call? If you know where it is, have you tried simply putting in the try catch where the catch is just 'break'? – Lord Windy Dec 08 '14 at 08:51
  • Let me know what is required – Skynet Dec 08 '14 at 08:52
  • Sorry, I didn't know what enter would just make the comment go. So I edited the information into my original one. EDIT: Also, instead of break put continue. I am an idiot and suggested the wrong one. – Lord Windy Dec 08 '14 at 08:55
  • A try catch and continue pattern just makes it to the next iteration of the loop - I lose this particular record. The application as I explained is doing intense calculations and its well guarded inside an Async task wherin I present a user with a loading dialog. – Skynet Dec 08 '14 at 09:58
  • Assuming when you say 'makes it' to the next iteration, I'm guessing that it gets to the next record and another exception is called? If that is the case ignore this, but instead of going 'continue' would it be possible to roll the program back a step (ie, if the loop is int i = 0; i < thingy; i++, than you could reverse everything you have done so far and at the end i--)? If that isn't the case than it might be required to go through and try to replace the offending code with something functionally equivalent. Would you be able to post the section of code or is it confidential? – Lord Windy Dec 08 '14 at 10:37
  • The code is not offending, it works perfectly well on other devices, I have analyzed the memory usinf the DDMS tools. This error occurs before the system calls System.gc(). Which however is not under my control, so I thought of using system.gc() manually however that is a bad programming practice and will not be feasible as I am not only targeting Note devices. Even if I roll back the complete operation, it is not guaranteed that I will not get this error at some point or the other - as and when memory consumption increases. – Skynet Dec 08 '14 at 10:42
  • The code is not confidential, however it is bulky I can paste the whole module here. – Skynet Dec 08 '14 at 10:45
  • I feel code is not culprit in this case. I observed the same issue if you create a new default project without any new code from you. – Ajay Dec 12 '14 at 08:07

2 Answers2

3

It seems to be a Samsung specific bug. It has been reported to

So far there does not seem to be a solution except updating your Android version (if I got that right).

kaolick
  • 4,817
  • 5
  • 42
  • 53
  • That all is known, we dont have an update for Note devices yet and my application is made for Note devices too, I checked about the bug in official Samsung forums but there is no response. Its bad how things have been kept and its a pain for the Developer. – Skynet Dec 08 '14 at 08:39
2

I would suggest to change the dbHelper.insert to be done inside a transaction this may walk-around the issue.

Although your code works is really slow and memory intensive so it may lead straight to an existing bug or occur only in "stressed" devices.

When you insert data to SQLite this way

 private void execQuery(String tableName,ContentValues val)
 {
    sqliteDb = instance.getWritableDatabase();       
    sqliteDb.insert(tableName, null, val);
    return true;
 }

the android method .insert performs a lot of safe checks and then insert them. This procedure I guess allocates a lot of memory and as I measured before takes a lot more execution time than the creation of transaction and inserting data on that.

String sql = "INSERT INTO table (col1, col2) VALUES (?, ?)";
db.beginTransaction();

SQLiteStatement stmt = db.compileStatement(sql);
for (int i = 0; i < values.size(); i++) {
    stmt.bindString(1, values.get(i).col1);
    stmt.bindString(2, values.get(i).col2);
    stmt.execute();
    stmt.clearBindings();
}

db.setTransactionSuccessful();
db.endTransaction();

Note that transaction should start before first insert and end after last insert not a transaction for each insert.

More about transactions at SO here.

I know that my answer may look too irrelevant to the question but I am quite positive that the error would be avoided that way and also the performance will be much improved. Sometimes is better to change the whole logic instead of handling the error.

Community
  • 1
  • 1
madlymad
  • 6,367
  • 6
  • 37
  • 68
  • Hi mate, I am too sorry I should have mentioned this in the question. I am already usiing transactions. That is why this bug is giving me terrible nights. I have optimized each and every way that I am aware of. I am using the try catch mechanism to start transactions at the try, setting them successful and ending them at finally. Thank you for the insightful answer :) – Skynet Dec 08 '14 at 11:44
  • 1
    That's too sad. The only think that I will then investigate in your code is `Scanner` as I am not used to use/see it in android apps. And can be blamed for memory allocating. A fast search revealed this http://stackoverflow.com/a/24304955/944070. Good luck! – madlymad Dec 08 '14 at 11:59
  • Thanks mate, advice followed there is only BufferedReader all around now, its sped up things more :) – Skynet Dec 08 '14 at 15:05
  • Nah it does, I am clueless as in how to avoid this now! – Skynet Dec 09 '14 at 03:21
  • Could you update the post with the way your code is improved? I guess it would make more sense. Also I take again a look an I start suspecting these: `publishProgress(progress); Asycdialog.setMax(lines); Asycdialog.incrementProgressBy(1);` do you have a progress `Dialog` android dialog? Have you tried to comment them? Just to see if it still reproducing the error. [I had bad experience with dialogs, although it was in another mobile platform and not Android] – madlymad Dec 13 '14 at 19:21