Throwing OutOfMemoryError "pthread_create (1040KB stack) failed: Try again" when doing asynchronous posts using Volley
Asked Answered
W

3

29

I'm using Volley to POST some data stored in a local database to a server. The problem is when I have a big number of entries (for example 500) I get this error:

 java.lang.OutOfMemoryError: pthread_create (1040KB stack) failed: Try again
at java.lang.Thread.nativeCreate(Native Method)
at com.android.volley.RequestQueue.start(RequestQueue.java:141)
at com.android.volley.toolbox.Volley.newRequestQueue(Volley.java:66)
at com.android.volley.toolbox.Volley.newRequestQueue(Volley.java:66)
at mypackageName.SomeClass.upload(SomeClass)
at mypackageName.MyClass$MyThred.run(SomeClass.java:387)

This is how I'm retrieving data from the cursor and doing the post

    private class UploadDataThred extends Thread {

    @Override
    public void run() {
        SomeSQLiteHelper someSQLiteHelper = new SomeSQLiteHelper(context);
        someSQLiteHelper.getWritableDatabase();
        Cursor result = someSQLiteHelper.getAllEvents();
        DataUploader dataUploader = new DataUploader(context);

        while (result.moveToNext()) {
            Build.logError("We're looping!");
            while (!waitingForResponse) {
                try {
                    Thread.sleep(4000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
            dataUploader.upload(result.getString(0), false, result.getString(1), result.getString(2), result.getString(3), result.getString(4), result.getString(5), result.getString(6), result.getString(7), result.getString(8));

        }
        someSQLiteHelper.close();
    }
}

and this is my method that does the POST

 public void upload(Some parameters go here) {

    waitingForResponse = true;
    VolleyLog.DEBUG = false;


    final JSONObject o = new JSONObject();
    o.put(Some data)

    RequestQueue requestQueue = Volley.newRequestQueue(context);

    JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.POST, HOST,  o, new Response.Listener<JSONObject>() {


        @Override
        public void onResponse(JSONObject response) {

            if (response.toString().contains("OK")) {

                if (columnID != null) {

                deleteSingleEntry(columnID);

                }


                waitingForResponse = false;


            }

        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {

            waitingForResponse = false;

        }
    }) {

        /**
         * Passing some request headers
         * */
        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            HashMap<String, String> headers = new HashMap<String, String>();
            headers.put("Content-Type", "application/json; charset=utf-8");
            return headers;
        }


    };



    requestQueue.add(jsonObjReq);

}

It work's fine if I've got 400 entries in the local db and after that it throws that execption. Thank you in advance.

Wheaten answered 29/2, 2016 at 13:59 Comment(0)
W
53

The problem is I was creating a new RequestQueue for every request. That's the reason I suspect it was throwing the OutOfMemory Exception. The solution is simple:

instead of RequestQueue requestQueue = Volley.newRequestQueue(context);

declare the RequestQueue outside the method and add a new RequestQueue only if the previous one is null.

private RequestQueue requestQueue;

public void uploadData(String s) {
if (requestQueue == null) {
        requestQueue = Volley.newRequestQueue(context);
        Build.logError("Setting a new request queue");
    } more request stuff....
}
Wheaten answered 1/3, 2016 at 8:57 Comment(1)
Thanks this was very helpful, but I still don't understand how there is no proper garbage collection?Syphilology
C
12

As a side note, I had the same error from socket.io, whenever I reconnected with socket.connect() new thread would start with old thread still running.

Solved it by calling socket.disconnect() before socket.connect(). Even though socket is already disconnected, calling socket.disconnect() will destroy old thread for you

It is not actually related to the question itself, but I had the same "outofmemoryerror pthread_create" error, which isn't caused by Volley but by socket.io creating new threads every time user tries to reconnect manually (by calling socket.connect, instead of setting "reconnect" option to true). When I was googling for the solution I came to this question and after fixing the problem decided to add the solution here, just in case someone else had the same problem

Chrysa answered 2/3, 2017 at 5:51 Comment(0)
J
0

I maybe a bit late here. The issue arises when new RequestQueue is being added unnecessarily and it just consumes a lot of memory. The trick is to check whether the requestqueue is null and if so create a new request or if it already exist just add to the existing request.

In your code, do something like this:

private RequestQueue requestQueue;// Declare


//In your Volley Call Method 

        if (requestQueue == null) {
        requestQueue = Volley.newRequestQueue(this);
        requestQueue.add(jsArrRequest);
    } else {
        requestQueue.add(jsArrRequest);
    }
Jaban answered 7/9, 2020 at 6:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.