| |||||||
Das Thema "AsyncTask verursacht OutOfMemory Exception" befindet sich unter Android App Entwicklung auf Android-Hilfe.de.
|
| | Themen-Optionen | Ansicht |
| | #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
| 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);
} 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. |
| | |
| | #2 (permalink) |
| Fortgeschrittenes Mitglied Registriert seit: 14.08.2009
Beiträge: 354
Abgegebene Danke: 23
Erhielt 49 Danke für 43 Beiträge
|
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/ |
| | |
| | #3 (permalink) |
| Android-Hilfe.de Mitglied |
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 |
| | |
| | #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
|
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. |
| | |
| | #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
|
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 ;-) |
| | |
| | #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
|
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? |
| | |
| | #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
|
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. |
| | |
| | #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
|
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();
}
}
} |
| | |
| Folgender Benutzer bedankt sich bei samarek für diesen Beitrag: | DieGoldeneMitte (22.11.2011) |
| | #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
|
hmm, ich denke Code: String sql = "INSERT INTO availability (EAN, vk6) VALUES (?, ?)";
SQLiteStatement stmt = db.compileStatement(sql); |
| | |
| | #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
|
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? |
| | |
![]() |
|
| Themen-Optionen | |
| Ansicht | |
| |
| ||||
| 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 |