在Android上使用SQLite时出现OutOfMemory异常

时间:2016-01-31 12:29:15

标签: java android exception

我目前正在使用内部SQLite API在我的应用程序中存储数据。基本上它只是一个IP,端口和密码列表。我在GetTerrariumList函数中得到随机异常,主要是data.set*方法。大部分时间都发生在SetAdressSetPassword

Database.java

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import java.util.ArrayList;

public class Database extends SQLiteOpenHelper {

    private static final int currentVersion = 1;
    private static final String databaseName = "MyHedgehogDB";
    private static final String ipListTable = "IPListTable";
    private static final String ipListTableID = "id";
    private static final String ipListTableAdress = "adress";
    private static final String ipListTablePort = "port";
    private static final String ipListTablePassword = "password";

    public Database(Context context) {
        super(context, databaseName, null, currentVersion);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE " + ipListTable + " (" + ipListTableID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
                + ipListTableAdress + " VARCHAR, "
                + ipListTablePort + " INTEGER, "
                + ipListTablePassword + " VARCHAR)");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + ipListTable);
        onCreate(db);
    }

    public ArrayList<TerrariumData> GetTerrariumList() {
        ArrayList<TerrariumData> result = new ArrayList<>();
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor res = db.rawQuery("SELECT " + ipListTableID + ", "
                + ipListTableAdress + ", "
                + ipListTablePort + ", "
                + ipListTablePassword
                + " FROM " + ipListTable, null);
        res.moveToFirst();
        while (res.isAfterLast() == false) {
            TerrariumData data = new TerrariumData();
            // ERROR OCCURS IN THE FOLLOWING LINES
            data.setID(res.getInt(res.getColumnIndex(ipListTableID)));
            data.setAdress(res.getString(res.getColumnIndex(ipListTableAdress)));
            data.setPort(res.getInt(res.getColumnIndex(ipListTablePort)));
            String temp = res.getString(res.getColumnIndex(ipListTablePassword));
            data.setPassword(res.getString(res.getColumnIndex(ipListTablePassword)));
            result.add(data);
            res.moveToNext();
        }
        return result;
    }

    public int AddTerrarium(String adress, int Port, String password) {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues contentValues = new ContentValues();
        contentValues.put(ipListTableAdress, adress);
        contentValues.put(ipListTablePort, Port);
        contentValues.put(ipListTablePassword, password);
        return (int)db.insert(ipListTable, null, contentValues);
    }

    public void DeleteTerrarium(int id) {
        SQLiteDatabase db = this.getWritableDatabase();
        db.delete(ipListTable, "id = ?", new String[] {Integer.toString(id)});
    }
}

TerrariumData.java (只是变量的getter和setter)

package net.dev_shack.myhedgehog;

public class TerrariumData {
    private int ID = -1;
    private String Name = "Unnamed";
    private String Adress = "localhost";
    private String Password = "";
    private int Port = 12312;
    private int NumSensors = 0;
    private int LightR = 0;
    private int LightG = 0;
    private int LightB = 0;
    private boolean LightStatus = false;
    private double Temperature = 0.0;
    private boolean HeatLamp = false;

    public boolean isError() {
        return Error;
    }

    public void setError(boolean error) {
        Error = error;
    }

    private boolean Error = false;

    public boolean isSensorsOK() {
        return SensorsOK;
    }

    public void setSensorsOK(boolean sensorsOK) {
        SensorsOK = sensorsOK;
    }

    private boolean SensorsOK = false;

    public boolean isHeatLamp() {
        return HeatLamp;
    }

    public void setHeatLamp(boolean heatLamp) {
        HeatLamp = heatLamp;
    }

    public boolean isLightStatus() {
        return LightStatus;
    }

    public void setLightStatus(boolean lightStatus) {
        LightStatus = lightStatus;
    }

    public boolean isDataValid() {
        return DataValid;
    }

    public void setDataValid(boolean dataValid) {
        DataValid = dataValid;
    }

    private boolean DataValid = false;

    public int getNumSensors() {
        return NumSensors;
    }

    public void setNumSensors(int numSensors) {
        NumSensors = numSensors;
    }

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    }

    public String getAdress() {
        return Adress;
    }

    public void setAdress(String adress) {
        Adress = adress;
    }

    public int getPort() {
        return Port;
    }

    public void setPort(int port) {
        Port = port;
    }

    public int getLightR() {
        return LightR;
    }

    public void setLightR(int lightR) {
        LightR = lightR;
    }

    public int getLightG() {
        return LightG;
    }

    public void setLightG(int lightG) {
        LightG = lightG;
    }

    public int getLightB() {
        return LightB;
    }

    public void setLightB(int lightB) {
        LightB = lightB;
    }

    public double getTemperature() {
        return Temperature;
    }

    public void setTemperature(double temperature) {
        Temperature = temperature;
    }

    public int getID() {
        return ID;
    }

    public void setID(int ID) {
        this.ID = ID;
    }

    public String getPassword() {
        return Password;
    }

    public void setPassword(String password) {
        Password = password;
    }
}

异常

01-31 13:22:37.825 14028-14028/net.dev_shack.myhedgehog E/art: Throwing OutOfMemoryError "Failed to allocate a 28 byte allocation with 1546896 free bytes and 1510KB until OOM; failed due to fragmentation (required continguous free 4096 bytes for a new buffer where largest contiguous free 0 bytes)" (recursive case)
01-31 13:22:37.825 14028-14038/net.dev_shack.myhedgehog I/art: Alloc partial concurrent mark sweep GC freed 0(0B) AllocSpace objects, 0(0B) LOS objects, 2% free, 62MB/64MB, paused 112us total 38.345ms
01-31 13:22:37.826 14028-14036/net.dev_shack.myhedgehog I/art: WaitForGcToComplete blocked for 86.301ms for cause Alloc
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art: "main" prio=5 tid=1 Runnable
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:   | group="main" sCount=0 dsCount=0 obj=0x74168000 self=0xb4025800
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:   | sysTid=14028 nice=0 cgrp=default sched=0/0 handle=0xb7756ea0
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:   | state=R schedstat=( 0 0 0 ) utm=181 stm=6 core=1 HZ=100
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:   | stack=0xbf64b000-0xbf64d000 stackSize=8MB
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:   | held mutexes= "mutator lock"(shared held)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:   native: #00 pc 00005d03  /system/lib/libbacktrace_libc++.so (UnwindCurrent::Unwind(unsigned int, ucontext*)+83)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:   native: #01 pc 00003051  /system/lib/libbacktrace_libc++.so (Backtrace::Unwind(unsigned int, ucontext*)+33)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:   native: #02 pc 003c9e67  /system/lib/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, int, char const*, art::mirror::ArtMethod*)+135)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:   native: #03 pc 0038f592  /system/lib/libart.so (art::Thread::DumpStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) const+290)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:   native: #04 pc 00395eab  /system/lib/libart.so (art::Thread::ThrowOutOfMemoryError(char const*)+459)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:   native: #05 pc 001f1efb  /system/lib/libart.so (art::gc::Heap::ThrowOutOfMemoryError(art::Thread*, unsigned int, art::gc::AllocatorType)+1243)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:   native: #06 pc 001f5ba5  /system/lib/libart.so (art::gc::Heap::AllocateInternalWithGc(art::Thread*, art::gc::AllocatorType, unsigned int, unsigned int*, unsigned int*, art::mirror::Class**)+2773)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:   native: #07 pc 0017e1bb  /system/lib/libart.so (art::mirror::Class::AllocObject(art::Thread*)+1275)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:   native: #08 pc 003950a4  /system/lib/libart.so (art::Thread::ThrowNewWrappedException(art::ThrowLocation const&, char const*, char const*)+820)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:   native: #09 pc 00395f52  /system/lib/libart.so (art::Thread::ThrowOutOfMemoryError(char const*)+626)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:   native: #10 pc 001f1efb  /system/lib/libart.so (art::gc::Heap::ThrowOutOfMemoryError(art::Thread*, unsigned int, art::gc::AllocatorType)+1243)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:   native: #11 pc 001f5ba5  /system/lib/libart.so (art::gc::Heap::AllocateInternalWithGc(art::Thread*, art::gc::AllocatorType, unsigned int, unsigned int*, unsigned int*, art::mirror::Class**)+2773)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:   native: #12 pc 0017e1bb  /system/lib/libart.so (art::mirror::Class::AllocObject(art::Thread*)+1275)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:   native: #13 pc 0031eda9  /system/lib/libart.so (art::mirror::String::Alloc(art::Thread*, int)+937)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:   native: #14 pc 0031f66d  /system/lib/libart.so (art::mirror::String::AllocFromUtf16(art::Thread*, int, unsigned short const*, int)+45)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:   native: #15 pc 002cb79b  /system/lib/libart.so (art::JNI::NewString(_JNIEnv*, unsigned short const*, int)+363)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:   native: #16 pc 0010ec4d  /system/lib/libart.so (art::CheckJNI::NewString(_JNIEnv*, unsigned short const*, int)+125)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:   native: #17 pc 000ac99d  /system/lib/libandroid_runtime.so (???)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:   native: #18 pc 00a27536  /data/dalvik-cache/x86/system@framework@boot.oat (Java_android_database_CursorWindow_nativeGetString__JII+154)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:     at android.database.CursorWindow.nativeGetString(Native method)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:     at android.database.CursorWindow.getString(CursorWindow.java:438)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:     at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:     at net.dev_shack.myhedgehog.Database.GetTerrariumList(Database.java:50)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:     at net.dev_shack.myhedgehog.MainActivity.onCreate(MainActivity.java:44)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:     at android.app.Activity.performCreate(Activity.java:5990)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:     at android.app.ActivityThread.access$800(ActivityThread.java:151)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:     at android.os.Handler.dispatchMessage(Handler.java:102)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:     at android.os.Looper.loop(Looper.java:135)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:     at android.app.ActivityThread.main(ActivityThread.java:5254)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:     at java.lang.reflect.Method.invoke!(Native method)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:     at java.lang.reflect.Method.invoke(Method.java:372)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
01-31 13:22:37.828 14028-14028/net.dev_shack.myhedgehog E/art:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
01-31 13:22:37.835 14028-14036/net.dev_shack.myhedgehog W/art: Suspending all threads took: 5.871ms
01-31 13:22:37.835 14028-14036/net.dev_shack.myhedgehog I/art: Alloc sticky concurrent mark sweep GC freed 0(0B) AllocSpace objects, 0(0B) LOS objects, 2% free, 62MB/64MB, paused 6.062ms total 9.708ms
01-31 13:22:37.881 14028-14038/net.dev_shack.myhedgehog I/art: Alloc concurrent mark sweep GC freed 1414046(61MB) AllocSpace objects, 0(0B) LOS objects, 50% free, 996KB/2020KB, paused 201us total 45.512ms
01-31 13:22:37.881 14028-14036/net.dev_shack.myhedgehog I/art: WaitForGcToComplete blocked for 39.894ms for cause Alloc
01-31 13:22:37.884 14028-14028/net.dev_shack.myhedgehog I/art: WaitForGcToComplete blocked for 43.182ms for cause Alloc
01-31 13:22:37.884 14028-14028/net.dev_shack.myhedgehog D/AndroidRuntime: Shutting down VM
01-31 13:22:37.885 14028-14028/net.dev_shack.myhedgehog E/AndroidRuntime: FATAL EXCEPTION: main
                                                                          Process: net.dev_shack.myhedgehog, PID: 14028
                                                                          java.lang.OutOfMemoryError: OutOfMemoryError thrown while trying to throw OutOfMemoryError; no stack available
01-31 13:22:37.886 14028-14038/net.dev_shack.myhedgehog E/System: java.lang.OutOfMemoryError: OutOfMemoryError thrown while trying to throw OutOfMemoryError; no stack available
01-31 13:22:37.886 14028-14036/net.dev_shack.myhedgehog W/System.err: java.lang.OutOfMemoryError: OutOfMemoryError thrown while trying to throw OutOfMemoryError; no stack available

2 个答案:

答案 0 :(得分:2)

您不会向前移动res,因此您的while循环将执行并反复添加相同的元素,直到内存耗尽。

答案 1 :(得分:0)

在while循环结束时,请尝试res.moveToNext();