Allocation error: amount = 1, size = 2081$L/cxunix.c

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
wannabeapro
User
Beiträge: 6
Registriert: Dienstag 11. Dezember 2012, 12:38

Guten Tag liebe Python-Gemeinde,

ich versuche nun seit längerem folgendes Problem zu lösen. Jedoch kann ich hier nicht genau definieren, ob es ein Fehlverständnis meiner seits zur Fehlermeldung ist.

Kurze Einführung zur Aufgabe des Programms:
Die Funktion des Programms bei welchem dieser Fehler auftritt ist das automatisierte einlesen von Stammdatendateien.
Hierzu wird die Datei, welche gerade Verarbeitet wird, komplett in eine Liste eingelesen.
In den weiteren Arbeitsschritten wird, nur noch auf die Liste zugegriffen und die Datei wurde bereits geschlossen.

Es ist zu erwähnen das ein Großteil des Programmablaufs in Funktionen stattfindet.

Hinzu tritt dieses Problem nur bei größeren Stammdatendateien auf.
Dateien <= 1,5MB = kein Problem

Aktuelle Testdatei, welche den Fehler erzeugt > 3MB

Fehlermeldung:
Allocation error: amount = 1, size = 2081$L/cxunix.c

Ich lese aus dieser Fehlermeldung, dass mein Programmablauf den zur Verfügung stehenden Speicher, welcher für diesen Prozess bereitgestellt wird, überschreitet.

Ist dies soweit erst mal korrekt?

Da der Fehler mitten im Programm auftritt, nachdem schon einige Artikel eingelesen wurden und das Programm aus mehr als 2000 Zeilen besteht, kann ich diesen Fehler nicht lokalisieren.

Was ich bisher getan habe:
1. Zu verarbeitende Datei erst in Liste einlesen und dann verarbeiten.
2. Es werden nach jedem eingelesen Artikel alle Verarbeitunsvariablen und Listen via 'del' gelöscht und Neu deklariert (bis auf die Liste in welcher der Dateiinhalt steht)

Evtl. könnt ihr mir ja mit diesen Informationen schon einen Tipp geben, für weitere Fragen stehe ich natürlich gerne zur Verfügung.

im Voraus schon mal vielen Dank für eure Mühe.

Gruß
wanna
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

Ohne Kenntnis dessen, was Du da im Detail tust, lässt sich natürlich nur raten. Wenn Du Deine Daten auch sequentiell (und nicht in einem Rutsch) einlesen und weiterverarbeiten kannst, dann solltest Du das auf diese Weise tun. Weiter wird mit 'del' nur ein Label entfernt (bzw. ein 'unbound' eines Objektes bewirkt, sofern das Objekt dies zulässt) . Das endgültige Löschen obliegt dem Garbage-Collector. Die Anwendung von 'del' bewirkt also nicht unbedingt eine direkte Speicherfreigabe.
wannabeapro
User
Beiträge: 6
Registriert: Dienstag 11. Dezember 2012, 12:38

Hallo,

ich werde Versuchen es noch etwas weiter aufzuschlüssen, damit es evtl verständlicher wird.

Die Stammdatendateien sind Textbasierend und Semikolon getrennt.

Je Artikel können 24 Sätze vorhanden sein, wobei hierzu beachten ist:

1. Satz = 1. Zeile
2. Satz = 2. Zeile
....
....
(Neuer Artikel)
1. Satz = x. Zeile

Also jeder Satz wird in einer separaten Zeile aufgeschlüsselt. Wechselt der Artikel so wird einfach wieder mit Satz 1 begonnen.
Es muss nicht jeder Satz pro Artikel vorkommen.

Aus diesem Grund gehe ich sowieso Zeile für Zeile durch, da jeder Satz unterschiedlich verarbeitet werden muss.

Habe es in der ersten Version direkt über die Datei gehandelt.
Also Datei öffnen, eine Zeile lesen und verarbeiten danach zweite Zeile lesen.

Dabei ist er noch früher mit dem selben Fehler ausgestiegen.

Im Hintergrund passieren dann sachen, wie Lieferantennr suchen, Mengeneinheiten anpassen usw.

Danach wird das ganze in eine Oracle-Datenbank geschrieben.


Bitte Entschuldigt das evtl wichtige Infos fehlen. Ich bin voll im Ablauf drin und erachte evtl. einiges für Selbstverständlich, was ihr an Infos braucht.
Zuletzt geändert von wannabeapro am Dienstag 11. Dezember 2012, 15:18, insgesamt 1-mal geändert.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

wannabeapro hat geschrieben:Dateien <= 1,5MB = kein Problem

Aktuelle Testdatei, welche den Fehler erzeugt > 3MB
Die Größe ist eigentlich keine. 3MB kann man auf heutigen Systemen in den Hauptspeicher lesen ohne sich auch nur einmal Gedanken darüber zu machen. Von welcher Python-Version reden wir hier eigentlich?

Irgendwas passiert im Kontext deiner Anwendung so dass der Speicher nicht mehr freigegeben wird. Das kann auch durchaus ein Bug in einem eingebundenen Modul sein. Bei cx_Oracle ist mir so etwas zwar noch nicht untergekommen, aber es kann natürlich auch dort sein und vielleicht verwendest du ja noch andere Dinge.

Vielleicht baust du auch irgendwo im Ablauf des Programms äußerst schwergewichtige Objekte auf und referenzierst die so untereinander, dass der Garbage Collector sie nicht ohne weiteres wieder freigeben kann.

Ohne detaillierten Code lässt sich nicht viel dazu sagen. Du könntest ja mal die Verarbeitungsschritte deaktivieren und der Reihe nach wieder einschalten bis der Fehler auftritt. Dann hast du schon mal einen Verdächtigen gefunden.
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

Hallo wannabeapro,

die Datei cxunix.c, in der der Fehler auftritt, legt ja nahe, dass es irgendwas mit der Datenbankanbindung zu tun hat. Ich weiß jetzt nicht, wie Du auf die Datenbank zugreifst. Wenn es einfach möglich ist, würde ich alle Datenbankaufrufe durch Dummy-Funktionen ersetzen oder auskommentieren und testen, ob der Fehler immer noch auftritt. Schreibst Du viele Einträge mit BLOBs? Ich hatte vor Jahren mal den Fall, dass ich mit dem Schreiben von ein paar hundertausend Datensätzen den ganzen Oracle-Server zum Absturz bringen konnte.
BlackJack

@wannabeapro: Das mit ``del`` hört sich sehr komisch an. Diese Anweisung ist in Programmen relativ exotisch. Insbesondere wenn Du meinst damit so etwas wie Speicherverwaltung machen zu können oder gar zu müssen, gehst Du mit ziemlicher Sicherheit falsch an die Sache heran.
wannabeapro
User
Beiträge: 6
Registriert: Dienstag 11. Dezember 2012, 12:38

Guten Morgen,

ich habe das ganze nun mal durchgetestet und jegliches schreiben in die Datenbank auskommentiert. Und siehe da, der Fehler taucht nicht auf.

@Sirius3 : Danke für den Tipp der war Gold wert!

@BlackJack : Dadurch das der Fehler nun doch an anderer Stelle ist, habe ich die 'Del' Geschichte rausgeschmissen und setze die Variablen einfach neu.
Also:
Liste = []
var = ""

Sobald ich die Datenbankgeschichte am Laufen habe, werde ich euch berichten woran es genau lag.

Besten Dank nochmal

Gruß
wanna
BlackJack

@wannabeapro: Wenn vorher davor die ``del``-Anweisungen standen ist das okay. Wenn das jetzt *statt* der ``del``-Anweisungen da steht, sieht es immer noch komisch aus. Nämlich nach dem Versuch manuell Speicherverwaltung zu betreiben.
wannabeapro
User
Beiträge: 6
Registriert: Dienstag 11. Dezember 2012, 12:38

@BlackJack: Eigentlich möchte ich nun nur sicherstellen, dass keine Restwerte vom vorherigen Artikel in einer Liste stehen.
Da schien mir diese Variante das einfachste.
Was wäre eine elegantere Lösung?
BlackJack

@wannabeapro: Ganz allgemein Funktionen. Ein neuer Funktionsaufruf bedeutet neue lokale Namen, also keine möglichen Reste vom letzten Funktionsaufruf. Zum Beispiel eine Funktion die alle Zeilen *eines* Datensatzes als Argument bekommt und den verarbeitet und in einer Schleife für jeden Datensatz aufgerufen wird.
wannabeapro
User
Beiträge: 6
Registriert: Dienstag 11. Dezember 2012, 12:38

@BlackJack : Du hast Recht! :oops:
So wie ich es jetzt habe, ist es doppelt. Erst leeren und dann überschreiben/Neu beschreiben.
Hätte mir auch auffallen können. :lol:

Mit den Funktionen arbeite ich ja schon.
wannabeapro
User
Beiträge: 6
Registriert: Dienstag 11. Dezember 2012, 12:38

Moin Moin,

ich wollte euch nur kurz mitteilen woran es gelegen hat.
Letztendlich lag es an einem DB Connect.

Dieser wurde in einer While-Schleife immer wieder erzeugt bis irgendwann das DB-Modul ausgestiegen ist.

Danke nochmal für eure Hilfe! Währe allein wohl bei weitem nicht so schnell darauf gekommen.

Spitzen Forum :!:

Gruß
Wanna

Edit: Thema kann geschlossen werden. :)
Antworten