【问题标题】:Throwing OutOfMemoryError "pthread_create (1040KB stack) failed: Try again" when doing asynchronous posts using Volley使用 Volley 进行异步发布时抛出 OutOfMemoryError "pthread_create (1040KB stack) failed: Try again"
【发布时间】:2016-02-29 13:59:49
【问题描述】:

我正在使用 Volley 将存储在本地数据库中的一些数据发布到服务器。问题是当我有大量条目(例如 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 个条目,然后它会抛出该 execption,那就没问题了。 提前谢谢你。

【问题讨论】:

    标签: android mobile android-volley


    【解决方案1】:

    问题是我为每个请求创建了一个新的 RequestQueue。这就是我怀疑它抛出 OutOfMemory 异常的原因。解决方法很简单:

    而不是RequestQueue requestQueue = Volley.newRequestQueue(context);

    在方法外声明RequestQueue,仅当前一个为null时才添加新的RequestQueue。

    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.connect() 之前调用 socket.disconnect() 解决了这个问题。即使 socket 已经断开,调用 socket.disconnect() 也会为你销毁旧线程

    它实际上与问题本身无关,但我有相同的“outofmemoryerror pthread_create”错误,这不是由 Volley 引起的,而是由 socket.io 每次用户尝试手动重新连接时创建新线程(通过调用 socket .connect,而不是将“重新连接”选项设置为 true)。当我在谷歌上搜索解决方案时,我遇到了这个问题,在解决问题后决定在这里添加解决方案,以防其他人遇到同样的问题

    【讨论】:

      【解决方案3】:

      我在这里可能有点晚了。 当不必要地添加新的RequestQueue 并且它只会消耗大量内存时,就会出现问题。 诀窍是检查请求队列是否为空,如果是则创建一个新请求,或者如果它已经存在,只需添加到现有请求中即可。

      在您的代码中,执行以下操作:

      private RequestQueue requestQueue;// Declare
      
      
      //In your Volley Call Method 
      
              if (requestQueue == null) {
              requestQueue = Volley.newRequestQueue(this);
              requestQueue.add(jsArrRequest);
          } else {
              requestQueue.add(jsArrRequest);
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-03
        • 2017-11-07
        • 1970-01-01
        相关资源
        最近更新 更多