Throwing OutOfMemoryError "pthread_create (стек 1040 КБ) не удалось: повторите попытку" при выполнении асинхронных сообщений с помощью Volley
Я использую Volley для POST некоторых данных, хранящихся в локальной базе данных на сервере. Проблема в том, что когда у меня большое количество записей (например, 500), я получаю эту ошибку:
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)
Вот как я извлекаю данные из курсора и делаю сообщение
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();
}
}
и это мой метод, который выполняет 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);
}
Он работает нормально, если у меня есть 400 записей в локальном db, и после этого он выдает это выполнение.
Заранее благодарю вас.
Ответы
Ответ 1
Проблема заключается в том, что я создавал новый RequestQueue для каждого запроса. Это причина, по которой я подозреваю, что это выбрасывает OutOfMemory Exception. Решение прост:
вместо RequestQueue requestQueue = Volley.newRequestQueue(context);
объявить RequestQueue вне метода и добавить новый RequestQueue только в том случае, если предыдущий имеет значение 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....
}
Ответ 2
В качестве побочного примечания, у меня была такая же ошибка из socket.io, всякий раз, когда я снова подключался к socket.connect(), новый поток начинался со старого потока, который все еще работает.
Решил его, вызвав socket.disconnect() перед socket.connect(). Даже если сокет уже отключен, вызов socket.disconnect() уничтожит старый поток для вас
На самом деле это не связано с самим вопросом, но у меня была такая же ошибка "outofmemoryerror pthread_create", которая не вызвана Volley, а socket.io, создавая новые потоки каждый раз, когда пользователь пытается повторно подключиться вручную (путем вызова сокета .connect, вместо установки опции "повторно подключить" к true). Когда я приступил к поиску решения, я пришел к этому вопросу, и после того, как проблема была решена, мы решили добавить решение здесь, на случай, если у кого-то была такая же проблема.