StringBuilder的超出内存 - 堆大小(16 MIB)大小、内存、StringBuilder、MIB

2023-09-03 22:32:11 作者:绿袖

我需要在这一个大的SQLite数据库,截至目前我行添加到表时,我的模拟器的堆大小为16 MIB,它崩溃下来说内存不足,32 MIB工作正常的应用程序。我使用StringBuilder为GET。

所以,我能做些什么在这一点?有没有办法来限制我的应用程序能够在某些手机有一定的堆大小使用?如果是特别,这怎么办呢?

在此先感谢,这是我的错误code:

  09-02 13:21:08.805:E / AndroidRuntime(482):致命异常:AsyncTask的#1
09-02 13:21:08.805:E / AndroidRuntime(482):java.lang.RuntimeException的:一个错误而执行doInBackground发生()
09-02 13:21:08.805:E / AndroidRuntime(482):在android.os.AsyncTask $ 3.done(AsyncTask.java:200)
09-02 13:21:08.805:E / AndroidRuntime(482):在java.util.concurrent.FutureTask中$ Sync.innerSetException(FutureTask.java:273)
09-02 13:21:08.805:E / AndroidRuntime(482):在java.util.concurrent.FutureTask.setException(FutureTask.java:124)
09-02 13:21:08.805:E / AndroidRuntime(482):在java.util.concurrent.FutureTask中$ Sync.innerRun(FutureTask.java:307)
09-02 13:21:08.805:E / AndroidRuntime(482):在java.util.concurrent.FutureTask.run(FutureTask.java:137)
09-02 13:21:08.805:E / AndroidRuntime(482):在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
09-02 13:21:08.805:E / AndroidRuntime(482):在java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:561)
09-02 13:21:08.805:E / AndroidRuntime(482):在java.lang.Thread.run(Thread.java:1096)
09-02 13:21:08.805:E / AndroidRuntime(482):由:java.lang.OutOfMemoryError
09-02 13:21:08.805:E / AndroidRuntime(482):在java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:97)
09-02 13:21:08.805:E / AndroidRuntime(482):在java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:136)
09-02 13:21:08.805:E / AndroidRuntime(482):在java.lang.StringBuilder.append(StringBuilder.java:272)
09-02 13:21:08.805:E / AndroidRuntime(482):在java.io.BufferedReader.readLine(BufferedReader.java:452)
09-02 13:21:08.805:E / AndroidRuntime(482):在com.ex.nok.Src.prodGet(Src.java:157)
09-02 13:21:08.805:E / AndroidRuntime(482):在com.ex.nok.MainActivity $ RestRequ.doInBackground(MainActivity.java:398)
09-02 13:21:08.805:E / AndroidRuntime(482):在com.ex.nok.MainActivity $ RestRequ.doInBackground(MainActivity.java:1)
09-02 13:21:08.805:E / AndroidRuntime(482):在android.os.AsyncTask $ 2.call(AsyncTask.java:185)
09-02 13:21:08.805:E / AndroidRuntime(482):在java.util.concurrent.FutureTask中$ Sync.innerRun(FutureTask.java:305)
09-02 13:21:08.805:E / AndroidRuntime(482):4 ...更多
 

下面就是我的StringBuilder的是,这将导致该问题:

 公共静态无效prodGet(活动的行为,串urlStr){

    INT productId参数;
    字符串产品名称;

    UrunSQLiteHelper dbProds =新UrunSQLiteHelper(行为);

    HttpURLConnection的康恩= NULL;
    BufferedReader中RD = NULL;
    尝试 {
        网址URL =新的URL(urlStr);
        康恩=(HttpURLConnection类)url.openConnection();
        conn.setConnectTimeout(6000);
        conn.setReadTimeout(10000);
        如果(conn.getResponse code()> = 200安培;&安培; conn.getResponse code()< 300){
            RD =新的BufferedReader(新的InputStreamReader(conn.getInputStream()));
            串线;
            而((行= rd.readLine())!= NULL){//< LT&;<<<<

                如果(线!= NULL || line.length()!= 0){
                JSONTokener prodTokener =新JSONTokener(线);
                JSONArray prodArray =新JSONArray(prodTokener);

                为(中间体H = 0; H≤(prodArray.length()); H + +)
                {
                    JSONObject的json_obj_prd = prodArray.getJSONObject(H);
                    productId参数= json_obj_prd.getString(PRODID);
                    产品名称= json_obj_prd.getString(PRODNAME);

                    dbProds.addProduct(新产品(productId参数,产品名称));
                }

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

            conn.disconnect();

        }
        其他 {
        }
    }
    赶上(例外五){
        Log.e(APP,例外,E);
    }
    最后 {
        如果(RD!= NULL){
            尝试 {
                rd.close();
            }赶上(IOException异常E){
            }
        }
        如果(conn将!= NULL){
            conn.disconnect();
        }
    }
}
 

解决方案

尝试 JsonReader ,而不是的BufferedReader

  JsonReader读卡器=新JsonReader(新InputStreamReader的(在UTF-8));
 
在ps时遇到图像超出了存储为web和设备所用格式的预期大小,该怎么办

JsonReader 的javadoc 提供了很好的例子,如何正确地执行它。

另外,您也可以使用第三方库如 GSON 或< A HREF =HTTP://jackson.$c$chaus.org/相对=nofollow>杰克逊

I have an application that requires a big SQLite database within it, now as I add rows to the tables when the heap size of my emulator is 16 MiB, it crashes down saying outofmemory, 32 MiB works fine. and I use a stringbuilder for GET.

So what can I do at this point? Is there a way to limit my application to be used on certain phones with certain heap sizes? If so specially, how can that be done?

Thanks in advance, here's my error code:

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

here's where my stringbuilder is, which causes the problem:

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();
        }
    }
}

解决方案

Try JsonReader instead BufferedReader

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

JsonReader javadoc provides nice example how to implement it properly.

Alternatively, you can use 3rd party libraries like GSON or Jackson.