【问题标题】:StringBuilder exceeds memory - heap size(16 mib)StringBuilder 超出内存 - 堆大小 (16 mib)
【发布时间】:2014-09-02 12:17:17
【问题描述】:

我有一个应用程序,其中需要一个大型 SQLite 数据库,现在当我的模拟器的堆大小为 16 MiB 时我向表中添加行时,它崩溃说内存不足,32 MiB 工作正常。我使用字符串生成器进行 GET。

那么此时我能做些什么呢?有没有办法限制我的应用程序在具有特定堆大小的某些手机上使用?如果是特别的,那怎么办?

提前致谢,这是我的错误代码:

09-02 13:21:08.805: E/AndroidRuntime(482): FATAL EXCEPTION: AsyncTask #1
09-02 13:21:08.805: E/AndroidRuntime(482): java.lang.RuntimeException: An error occured while executing doInBackground()
09-02 13:21:08.805: E/AndroidRuntime(482):  at android.os.AsyncTask$3.done(AsyncTask.java:200)
09-02 13:21:08.805: E/AndroidRuntime(482):  at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
09-02 13:21:08.805: E/AndroidRuntime(482):  at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
09-02 13:21:08.805: E/AndroidRuntime(482):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
09-02 13:21:08.805: E/AndroidRuntime(482):  at java.util.concurrent.FutureTask.run(FutureTask.java:137)
09-02 13:21:08.805: E/AndroidRuntime(482):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
09-02 13:21:08.805: E/AndroidRuntime(482):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
09-02 13:21:08.805: E/AndroidRuntime(482):  at java.lang.Thread.run(Thread.java:1096)
09-02 13:21:08.805: E/AndroidRuntime(482): Caused by: java.lang.OutOfMemoryError
09-02 13:21:08.805: E/AndroidRuntime(482):  at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:97)
09-02 13:21:08.805: E/AndroidRuntime(482):  at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:136)
09-02 13:21:08.805: E/AndroidRuntime(482):  at java.lang.StringBuilder.append(StringBuilder.java:272)
09-02 13:21:08.805: E/AndroidRuntime(482):  at java.io.BufferedReader.readLine(BufferedReader.java:452)
09-02 13:21:08.805: E/AndroidRuntime(482):  at com.ex.nok.Src.prodGet(Src.java:157)
09-02 13:21:08.805: E/AndroidRuntime(482):  at com.ex.nok.MainActivity$RestRequ.doInBackground(MainActivity.java:398)
09-02 13:21:08.805: E/AndroidRuntime(482):  at com.ex.nok.MainActivity$RestRequ.doInBackground(MainActivity.java:1)
09-02 13:21:08.805: E/AndroidRuntime(482):  at android.os.AsyncTask$2.call(AsyncTask.java:185)
09-02 13:21:08.805: E/AndroidRuntime(482):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
09-02 13:21:08.805: E/AndroidRuntime(482):  ... 4 more

这是我的字符串生成器所在的位置,这会导致问题:

public static void prodGet (Activity act, String urlStr) {

    int productId;
    String productName;

    UrunSQLiteHelper dbProds = new UrunSQLiteHelper(act);

    HttpURLConnection conn = null;
    BufferedReader rd = null;
    try {
        URL url = new URL(urlStr);
        conn = (HttpURLConnection) url.openConnection();
        conn.setConnectTimeout(6000);
        conn.setReadTimeout(10000);
        if (conn.getResponseCode() >= 200 && conn.getResponseCode() < 300) {
            rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = rd.readLine()) != null) { //<<<<<<

                if (line != null || line.length() != 0) {
                JSONTokener prodTokener = new JSONTokener(line);
                JSONArray prodArray = new JSONArray(prodTokener);

                for(int h=0; h<(prodArray.length()); h++)
                {
                    JSONObject json_obj_prd = prodArray.getJSONObject(h);
                    productId = json_obj_prd.getString("PRODID");
                    productName = json_obj_prd.getString("PRODNAME");

                    dbProds.addProduct(new Product(productId, productName));
                }

                dbProds.close();
                }
            }
            rd.close();

            conn.disconnect();

        }
        else {
        }
    }
    catch (Exception e) {
        Log.e("APP", "exception", e);
    }
    finally {
        if (rd != null) {
            try {
                rd.close();
            } catch (IOException e) {
            }
        }
        if (conn != null) {
            conn.disconnect();
        }
    }
}

【问题讨论】:

  • 这与 SQLite 有什么关系?一些StringBuilder 变得太大。
  • 谢谢,但我该如何解决呢?
  • StringBuilder 的代码是做什么用的?
  • question is what contains this response ...如果JSON然后使用一些流解析...如果数据库本身(我怀疑但是...)不将它存储在stringbuilder中,而是写入文件下载时间,如果每行 INSERT 语句 - 然后执行该行并且不存储......换句话说,根本不使用 stringbuilder - “消费”数据飞

标签: android sqlite heap-memory heap-size


【解决方案1】:

尝试JsonReader 而不是BufferedReader

JsonReader reader = new JsonReader(new InputStreamReader(in, "UTF-8"));

JsonReader javadoc 提供了如何正确实现它的好例子。

或者,您可以使用 3rd 方库,例如 GSONJackson

【讨论】:

  • 这是一个很好的解决方案,但我需要能够将它用于 API 级别
  • 然后使用其中一个库。两者都提供 Streaming API。 Jackson 认为自己是最有效率的,所以先试试吧。
  • 好的,如果你这么说,我会这样做,非常感谢,抱歉回复晚了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-12
  • 1970-01-01
  • 2015-10-24
  • 2015-12-29
  • 2017-12-27
  • 2020-12-06
相关资源
最近更新 更多