Jetzt kostenlos registrieren. Mitglieder surfen ohne Werbung auf Android-Hilfe.de!
Zurück   Android-Hilfe.de > Android Developer > Android App Entwicklung

AsyncTask verursacht OutOfMemory Exception

Das Thema "AsyncTask verursacht OutOfMemory Exception" befindet sich unter Android App Entwicklung auf Android-Hilfe.de.


Antwort

 

Themen-Optionen Ansicht
Alt 16.11.2011, 15:27   #1 (permalink)
Android-Hilfe.de Mitglied

Modell: Samsung Galaxy S2 (I9100)

Registriert seit: 24.10.2011
Beiträge: 77
Abgegebene Danke: 13
Erhielt 2 Danke für 2 Beiträge
Standard AsyncTask verursacht OutOfMemory Exception

Hi,

ich hab folgendes Problem und zwar ...

führe ich beim start meiner App einen AsyncTask aus, der Daten aus einer fast 6mb großen JSON-Datei liest und die in eine Datenbank schreibt.
Wobei die App dann nach nicht allzulanger Zeit eine absehbare "OutOfMemoryException" auslöst.

hier ist mal ein vergleichbarer Quellcodeteil (der echte ist noch einiges länger)
Code:
InputStream is = context.getResources().openRawResource(availibilityJson);
        BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
        StringBuilder alles = new StringBuilder();
        String line;
        while ((line = br.readLine()) != null)
        {
            alles.append(line);
        }
        is.close();
        jsonArray = new JSONArray(alles.toString());
        for (int i = 0; i < jsonArray.length(); i++)
        {
            JSONObject obj = jsonArray.getJSONObject(i);
            String ean = obj.getString("EAN").trim();
            String vk6 = obj.getString("vk6").trim();
            Availability availability = new Availability(ean, vk6);
            Datenbank.availibilityEintragen(availability);
        }
Meine Frage ist jetzt, wie kann ich diesen Code ein wenig "glätten" damit er nicht mit so großen Datenmengen hantieren muss?
Also quasi 100 Datensätze lesen und in die Datenbank schreiben, dann wieder alles aus dem Speicher schmeissen und die nächsten 100 Datensätze verarbeiten.
samarek ist offline   Mit Zitat antworten
Alt 16.11.2011, 15:50   #2 (permalink)
Fortgeschrittenes Mitglied

Registriert seit: 14.08.2009
Beiträge: 354
Abgegebene Danke: 23
Erhielt 49 Danke für 43 Beiträge
Standard AW: AsyncTask verursacht OutOfMemory Exception

JSONObject zu nutzen bei so großen Datenmengen ist vllt nicht das richtige. Evtl. auf ein SAX Parser umstellen. und du solltest nicht unnütz "Availability" Objekte erzeugen um dise dann zu übergeben, kannst die Daten auch direkt in die DB eintragen. Was du noch probieren könntest, die Objekte wenn du sie nicht mehr brauchst auf NULL zu setzen und hoffe das der GC ordentlich aufräumt.

Desweiteren solltest du ordentliche Variablen Namen verwenden und keine Mischung zwischen Deutsch und Englisch machen oO

Gruß
Michael
__________________
http://android.fungamer.net/
MichaelS ist offline   Mit Zitat antworten
Alt 16.11.2011, 15:52   #3 (permalink)
Android-Hilfe.de Mitglied

Modell: Motorola Atrix 4G

Registriert seit: 07.12.2010
Beiträge: 170
Abgegebene Danke: 14
Erhielt 32 Danke für 31 Beiträge
Neeldarax eine Nachricht über ICQ schicken
Standard AW: AsyncTask verursacht OutOfMemory Exception

Hi samarek,

was sagt den der logcat genau dazu? Also mich interessieren die GC_ Einträge zwischen dem Start und dem OFME.

Hier gibt auch was zu lesen Designing for Performance | Android Developers
Mir hatte es etwas geholfen.

Wenn du dazu noch was nützliches erfährst, würde es mich auch interessieren. Auf solche Probleme stoße ich in letzter Zeit öfters

regards
__________________
g o o g l e+ plus.neeldarax.de
androidblog www.neeldarax.de
Neeldarax ist offline   Mit Zitat antworten
Alt 21.11.2011, 13:55   #4 (permalink)
Android-Hilfe.de Mitglied

Modell: Samsung Galaxy S2 (I9100)

Registriert seit: 24.10.2011
Beiträge: 77
Abgegebene Danke: 13
Erhielt 2 Danke für 2 Beiträge
Standard AW: AsyncTask verursacht OutOfMemory Exception

Soo hab es jetzt hinbekommen, schien echt daran zuliegen dass er soviele Objekte erzeugen musste.

Jetzt laufen alle 4 "Sachen aus JSON in die Datenbank schreiben" Tasks vernünftig durch.

Allerdings hab ich jetzt das Problem dass das eintragen der 6mb Datei über 10 Minuten dauert, das läuft natürlich im Prinzip nur bei der ersten Initialisierung durch, aber ist dennoch viel zu lang.
Weiss da vielleicht jemand Möglichkeiten wie sich das einlesen von JSON weiter optimieren lässt, also mindestens um die Hälfte müsste ich die Zeit schon noch drücken die das "in die Datenbank schreiben" im Moment braucht.
samarek ist offline   Mit Zitat antworten
Alt 22.11.2011, 07:42   #5 (permalink)
Fortgeschrittenes Mitglied

Modell: HTC Sensation

Registriert seit: 31.08.2011
Beiträge: 390
Abgegebene Danke: 25
Erhielt 59 Danke für 57 Beiträge
Standard AW: AsyncTask verursacht OutOfMemory Exception

Ich weiß nicht, ob man bei Android und SQLite Prepared Statements und Transaktionen benutzen kann (hab es bis jetzt nicht benötigt).

Aber im normalen Java mit JDBC hab ich bei Datenimporten durch Prepared Statements und Transaktionen schon öfter 50% Zeit gespart. Wäre sicherlich ein Versuch wert ;-)
Tom299 ist offline   Mit Zitat antworten
Alt 22.11.2011, 10:29   #6 (permalink)
Android-Hilfe.de Mitglied

Modell: Samsung Galaxy S2 (I9100)

Registriert seit: 24.10.2011
Beiträge: 77
Abgegebene Danke: 13
Erhielt 2 Danke für 2 Beiträge
Standard AW: AsyncTask verursacht OutOfMemory Exception

Ja, Android unterstützt Transaktionen und Prepared Statements

Ich hab jetzt mit Hilfe von preparedStatements und Transaktionen das Ausführen aller 4 Tasks von ca. 15 Minuten auf 22 Sekunden (!!!) reduziert.
Mehrfach getestet alle Daten sind da, Freunde sagen dass ist durchaus im Bereich des Möglichen, aber ich kann es nicht ganz glauben.

Was sagt ihr dazu?
samarek ist offline   Mit Zitat antworten
Alt 22.11.2011, 10:41   #7 (permalink)
Fortgeschrittenes Mitglied

Modell: HTC Sensation

Registriert seit: 31.08.2011
Beiträge: 390
Abgegebene Danke: 25
Erhielt 59 Danke für 57 Beiträge
Standard AW: AsyncTask verursacht OutOfMemory Exception

Na wenn du es mehrfach getestet hast und alle Daten da sind, dann wirds schon stimmen

Kannst mal den Teil mit den Statements posten? Würd mich mal interessieren, wie der Code dazu aussieht.
Tom299 ist offline   Mit Zitat antworten
Alt 22.11.2011, 11:07   #8 (permalink)
Android-Hilfe.de Mitglied

Modell: Samsung Galaxy S2 (I9100)

Registriert seit: 24.10.2011
Beiträge: 77
Abgegebene Danke: 13
Erhielt 2 Danke für 2 Beiträge
Standard AW: AsyncTask verursacht OutOfMemory Exception

Hier mal die Kurzversion einer der Methoden, geht sicher noch schöner, aber bin erstmal froh dass es läuft

Code:
public static boolean availabilityEintragen(String ean, String vk6, int i, boolean letzter)
    {
        if ((i % 1000) == 0)
        {
            db.beginTransaction();
        }
        try
        {
            String sql = "INSERT INTO availability (EAN, vk6) VALUES (?, ?)"; 
            SQLiteStatement stmt = db.compileStatement(sql);
            stmt.bindString(1, ean);
            stmt.bindString(2, vk6);
            stmt.execute();
            if ((i % 1000) == 999 || letzter)
            {
                db.setTransactionSuccessful();
            }
            return true;
        }
        catch (Exception exc)
        {
            Log.v("Exception", exc.getMessage());
            return false;
        }
        finally
        {
            if ((i % 1000) == 999 || letzter)
            {
                db.endTransaction();
            }
        }
    }
1000 Inserts werden zu einer Transaktion zusammengefasst und beim letzten Datensatz wird die laufende Transaktion beendet
samarek ist offline   Mit Zitat antworten
Folgender Benutzer bedankt sich bei samarek für diesen Beitrag:
DieGoldeneMitte (22.11.2011)
Alt 22.11.2011, 11:40   #9 (permalink)
Fortgeschrittenes Mitglied

Modell: HTC Sensation

Registriert seit: 31.08.2011
Beiträge: 390
Abgegebene Danke: 25
Erhielt 59 Danke für 57 Beiträge
Standard AW: AsyncTask verursacht OutOfMemory Exception

hmm, ich denke
Code:
            String sql = "INSERT INTO availability (EAN, vk6) VALUES (?, ?)"; 
            SQLiteStatement stmt = db.compileStatement(sql);
gehört nicht in die Schleife, weil du ja jedes mal das Statement neu erstellst. Glaub in die Schleife kommt nur noch das bind und das execute rein, oder?
Tom299 ist offline   Mit Zitat antworten
Alt 22.11.2011, 12:23   #10 (permalink)
Android-Hilfe.de Mitglied

Modell: Samsung Galaxy S2 (I9100)

Registriert seit: 24.10.2011
Beiträge: 77
Abgegebene Danke: 13
Erhielt 2 Danke für 2 Beiträge
Standard AW: AsyncTask verursacht OutOfMemory Exception

Die Methode wird in einer Schleife aufgerufen, in der Methode selber gibt es keine Schleife.
Wäre es denn soviel sinnvoller das Statement und den String ausserhalb zu erzeugen und dann jedesmal an die Methode zu übergeben?
samarek ist offline   Mit Zitat antworten
Antwort

Stichworte
-

Themen-Optionen
Ansicht


Ähnliche Themen

Thema Autor Forum Antworten Letzter Beitrag
Kommunikation zwischen AsyncTask und Activity? user7 Android App Entwicklung 4 16.03.2011 10:05
AsyncTask (progressdialog parallel anzeigen) mr.freeze Android App Entwicklung 13 28.02.2011 19:19
OutOfMemory - Canvas funcoder Android App Entwicklung 3 08.12.2010 17:45
AsyncTask, GPS, was muss parallel laufen? Artwork Android App Entwicklung 0 07.08.2010 15:24
OutofMemory beim Dateieinlesen GMoN Android App Entwicklung 2 29.04.2009 17:47




Du liest gerade: "AsyncTask verursacht OutOfMemory Exception" unter "Android App Entwicklung" auf Android-Hilfe.de.


Powered by vBulletin®
Copyright ©2000 - 2012, vBulletin Solutions, Inc.
Search Engine Friendly URLs by vBSEO
© Android-Hilfe.de 2012 - All rights reserved.