Seite 1 von 1

DbUseArea() und MemoryHandles

Verfasst: Mo, 08. Okt 2018 15:17
von Jan
Hallo,

in einem Programmmodul öffne ich eine dbf, kontrolliere einige Daten, und schließe die dbf wieder. Das mache ich im 1/2-Sekunden-Takt. Wir brauchen jetzt nicht zu diskutieren ob solch eine Vorgehensweise sinnvoll ist oder nicht. Es geht um etwas anderes.

Dieses Programm, in dem vier Threads im 1/2-Sekunden-Takt arbeiten (einer davon der oben beschriebene), stürzt in längeren Abständen (mehrere Tage) kommentarlos ab. Einfach weg. Ich hab dann mal den MemWatch eingebunden und dort gesehen, das die Memory Handles rasant in die Höhe gehen. Als Quelle konnte ich den oben beschriebenen Thread identifizieren.

Ich hab dann mal testweise die dbf nicht am Ende der Schleife geschlossen. Und beim Eintritt in die Thread-Funktion abgefragt, ob die schon offen ist - wenn nicht, wird die geöffnet, ansonsten halt eben nicht. Und siehe da, die Handles bleiben wie sie sind.

Jetzt bin ich leicht irritiert. Warum springen die Memory Handles beim Öffnen einer dbf nach oben, und werden auch nicht wieder frei gegeben?

Ergänzung: Das läuft alles auf einem ADS 12.1. Auch in den anderen Threads werden dbf geöffnet. Da scheint das aber komplett ohne Nebenwirkungen auf die Memory Handles zu laufen. Der Unterschied ist: In dem betreffenden Thread ist der dbf-Name 12 Zeichen lang. Also kürze ich den beim Öffnen in der Alias-Angabe auf 10, da der ADS ja nichts über 10 Stellen mag. Aber das kann doch wohl nicht der Grund sein, oder?

Jan

Re: DbUseArea() und MemoryHandles

Verfasst: Mo, 08. Okt 2018 15:29
von brandelh
2 mal je Sekunde ... ich hätte an cache oder an Überlastung des GC gedacht.
Beim Öffnen von Dateien muss ja cache eingelesen und wie du schreibst auch strings verarbeitet werden ...

Ich habe auch eine Routine die sehr viel Text einliest umsetzt und in DBF wegschreibt, diesem Thread habe ich ein sleep(1) eingebaut, damit der GC im Hintergrund genug Zeit hat.
Das hat bei mir keine Verzögerung gegeben und durch den Einbau in einen Thread (und disablen der gefährlichen Buttons) kann ich das restliche Programm sogar sauber bedienen.

Re: DbUseArea() und MemoryHandles

Verfasst: Mo, 08. Okt 2018 15:40
von Jan
Hallo Hubert,

in diese dbf schreibe ich fast nie etwas hinein. Ich kontrolliere nur, ob was zu tun ist (fast nie), und würde in dem Fall ein logisches Feld von .T. auf .F. setzen.

Jan

Re: DbUseArea() und MemoryHandles

Verfasst: Mo, 08. Okt 2018 16:32
von brandelh
Ich meinte nicht das Schreiben in die DBF, sondern die String Operationen die du für den Namen etc. machen musst, aber auch das öffnen und schließen von Dateien kostet Zeit und handles.
Ob das ein Problem darstellt weiß ich nicht, aber ein Thread der endlos Zeit verbraucht sollte mit sleep(0) oder 1 zur Kooperation überredet werden, damit die anderen Threads auch noch Rechenzeit bekommen.

Re: DbUseArea() und MemoryHandles

Verfasst: Mo, 08. Okt 2018 19:06
von ramses
Jan

bist du sicher dass ADS mehr als 8+3 Zeichen als Dateinamen zulässt?

Gruss Carlo

Re: DbUseArea() und MemoryHandles

Verfasst: Di, 09. Okt 2018 6:52
von Jan
Moin Carlo,

ja. 10 Zeichen sind für den Alias zulässig. Der Dateiname selber darf länger sein.

Jan

Re: DbUseArea() und MemoryHandles

Verfasst: Di, 09. Okt 2018 7:58
von Jan
Moin Hubert,

der Einbau eines Sleep(1) bringt überhaupt nichts. Die Memory Handles gehen bei jedem Öffnen (oder Schließen?) wieder massiv hoch.

Jan

Re: DbUseArea() und MemoryHandles

Verfasst: Di, 09. Okt 2018 10:35
von brandelh
der Einbau eines Sleep(1) bringt überhaupt nichts.
dann ist es kein Zeit / Überlastungsproblem, die Speicherbereiche / handles werden wohl nicht sauber freigegeben.

Sowas hatte ich wegen einem Fehler in der OT4XB auch, als ich viele tausend PDF mit QuickPDF erzeugt habe, damals habe ich Pablo angeschrieben und er hat ein Speicherleck bei sich festgestellt ...

Du wirst nicht umhin kommen, Alaska mit deinem Code zu belästigen, damit die nachsehen ob in der ADSDBE ein Fehler enthalten ist, der sich so auswirkt.

Re: DbUseArea() und MemoryHandles

Verfasst: Di, 09. Okt 2018 10:54
von Manfred
Jan,
kannst Du mal spasseshalber den Code zeigen, wie Du das machst?

Re: DbUseArea() und MemoryHandles

Verfasst: Di, 09. Okt 2018 11:02
von Tom
Aber das hier (PDR aus der 1.9.331, aber immer noch offen) ist es nicht, oder?

http://www.alaska-software.com/scripts/ ... PDRID=5993

Was geschieht, wenn Du statt des Sleep() einfach mal den Zyklus auf 2 oder 5 Sekunden erhöhst? Aber der CG kann es eigentlich nicht sein - eine halbe Sekunde sind für einen zügigen Rechner Jahrzehnte.

Re: DbUseArea() und MemoryHandles

Verfasst: Di, 09. Okt 2018 11:06
von Jan
Tom,

das sieht gut aus. Ich werd mal Alaska fragen, wie es mit dem PDR aussieht.

Jan

Re: DbUseArea() und MemoryHandles

Verfasst: Mi, 10. Okt 2018 12:35
von Jan
Ich hab das mit dem PDR 5993 mal bei Alaska angefragt. Der ist eindeutig noch offen. Es ist aber gegenwärtig/kurzfristig nicht geplant, was an der ADSDBE zu machen. Dumm gelaufen für mich. Für die PGDBE wird alles sofort gemacht. Alle anderen DBE bleiben ungefixt (ich hab da noch ein paar PDR in dem Bereich offen, die auch schon seit Jahren offen bleiben).

Jan

Re: DbUseArea() und MemoryHandles

Verfasst: Mi, 10. Okt 2018 17:37
von ramses
Jan

versuch doch mal den Code im Thread nicht als Schleife auszuführen sondern jeweils einen neuen Thread zu starten der den Code erneut ausführt.
Für die PGDBE wird alles sofort gemacht.

Bist du da sicher? Dauert ein USE auf eine grosse Datenbank nicht mehr Minuten?

Gruss Carlo

Re: DbUseArea() und MemoryHandles

Verfasst: Mi, 10. Okt 2018 18:15
von Tom
Die Kapazitäten sind halt begrenzt. :wink:

Kannst Du nicht das, was Du weiter oben aus Testzwecken implementiert hattest, in eine dauerhafte Lösung überführen? Damit hättest Du dann auch noch einen Performancegewinn.

Re: DbUseArea() und MemoryHandles

Verfasst: Mi, 10. Okt 2018 19:53
von Jan
Tom,

im Moment läuft das im Dauermodus. Also dbf beim ersten Threaddurchlauf öffnen, und dann offen halten. Alles andere geht ja nicht, ganz praktisch gesehen.

Blöd ist das aber trotzdem. Bei dem Kunden laufen viele Programme, wo die dbf teilweise bei Bedarf geöffnet werden. Bei Weitem nicht so massiv wie bei dem oben geschilderten Problemfall. Aber eben doch. Und jedes Öffnen und Schließen treibt den Speicher wieder hoch. Das ist echt blöd sowas.

Jan

Re: DbUseArea() und MemoryHandles

Verfasst: Mi, 10. Okt 2018 20:26
von ramses
Jan
ich habe auch ein Programm welches Messwerte im 5 Sekunden Takt wegschreibt. Dieses öffnet auch jedesmal über die ADSDBE eine DBF und läuft über Monate ohne Probleme. Ich habe jedoch keine Schlaufe wie du sondern starte den Thread alle 5 Sekunden neu.

Gruss Carlo

Re: DbUseArea() und MemoryHandles

Verfasst: Mi, 10. Okt 2018 20:38
von Jan
Carlo,

wie machst Du das, den Thread alle 5 Sekunden neu zu starten? Aber abgesehen davon - so wie ich den PDR verstehe ist das vollkommen egal, wie das gemacht wird - dbf öffnen und schließen klaut jedes Mal Speicher.

Jan

Re: DbUseArea() und MemoryHandles

Verfasst: Mi, 10. Okt 2018 22:24
von ramses
Hallo Jan

einen Thread bezw. die Funktion kannst du z.B. so neu aufrufen:

Code: Alles auswählen

oThread := Thread():new()
oThread:setInterval( 500 )
oThread:start( {||Funktion2run()}  )
Hast du mal versucht in den Alaska Runtime die ace32.dll und axcws32.dll gegen neuere aktuelle Version zu Updaten? Ich verwende die Version 10.10.0.49 und NICHT die Verion 7 welche Alaska jeweils ausliefert. Die 7. er Version macht Probleme vielleicht auch deines ..... und es fehlen auch Funktionen die ich für API-Calls benötige.


Der folgente Testcode läuft bis jetzt 500'000 Mal durch ohne ersichtliche Änderung im Speicherbedarf. (Natürlich ist ADSDBE default und Connected)

Code: Alles auswählen

   i := 0
  do while .t.
     sele 0
     use j:\modbus\modbus1.dbf via adsdbe 
     i ++
     ? i , text
     close database
  enddo


Gruss Carlo

Re: DbUseArea() und MemoryHandles

Verfasst: Do, 11. Okt 2018 7:55
von Jan
Carlo,

ich arbeite ebenfalls mit SetIntervall(). Und den ADS-Runtimes 11.10.

Jan

Re: DbUseArea() und MemoryHandles

Verfasst: Do, 11. Okt 2018 8:26
von ramses
Jan

merkwürdig.....

Meine oben erwähnte Programmschleife läuft noch immer. Viel Mio. mal durchgelaufen. Der Speicherbedarf der EXE ist noch immer gleich wie beim Start.

Gruss Carlo

Re: DbUseArea() und MemoryHandles

Verfasst: Do, 11. Okt 2018 8:51
von UliTs
Vielleicht wird beim Beenden des Thread ja tatsächlich auch die Tabelle korrekt geschlossen.
Idee für einen Workaround:
Thread schreiben, der alle 0,5 Sekunden einen neuen Thread startet, in dem die Tabelle geöffnet und wieder geschlossen wird.