Speicher läuft voll [Erledigt]

Moderator: Moderatoren

Benutzeravatar
Marcus Herz
1000 working lines a day
1000 working lines a day
Beiträge: 851
Registriert: Mo, 16. Jan 2006 8:13
Wohnort: Allgäu
Hat sich bedankt: 39 Mal
Danksagung erhalten: 192 Mal
Kontaktdaten:

Re: Speicher läuft voll

Beitrag von Marcus Herz »

Wo liegt dann der Unterschied zu meinen Tests?

Ich habe 4500 PDFs in einer Schleife sequentiell oder in mehrenen Threads paralell erzeugt und konnte über den Taskmanager keinen dauerhaft ansteigenden Speicherverlust feststellen.
Es wurde einmalig mehr Speicher angefordert, aber der Wert blieb dann relativ konstant. Während des Exports stieg er dann schon an,
aber nach ner Weile (Garbagecollector) ging der Speicher wieder zurück.
Gruß Marcus

Erkenne, was du findest, dann weißt du, wonach du gesucht hast
ramses
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2513
Registriert: Mi, 28. Jul 2010 17:16
Hat sich bedankt: 12 Mal
Danksagung erhalten: 77 Mal

Re: Speicher läuft voll

Beitrag von ramses »

Wenn ich das wüsste.
Meine PDF's werden in verschiedenen Threads des Programms(Dienst) erzeugt. Aber das war auch immer schon so. Die belegten xbase Mem-Handles sind auch immer etwa bei 10000-14000 da sieht man keinen Unterschied in den Logs.
Valar Morghulis

Gruss Carlo
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: Speicher läuft voll

Beitrag von AUGE_OHR »

hi Carlos,

wenn es bei "anderen" funktioniert würde ich mir den Source noch mal genauer ansehen.
ich habe das Gefühlt das du die Threads nicht (richtig) beendest und deshalb der Speicher voll läuft

packe doch mal diesen CODE in deine App und "kontrolliere" was im Speicher rum hängt

Code: Alles auswählen

   aInfo := ThreadInfo( THREADINFO_TID      + ;
                        THREADINFO_SYSTHND  + ;
                        THREADINFO_FUNCINFO + ;
                        THREADINFO_TOBJ       )

   AEval( aInfo, {|a| QOut( Var2Char(a) ) } )
gruss by OHR
Jimmy
ramses
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2513
Registriert: Mi, 28. Jul 2010 17:16
Hat sich bedankt: 12 Mal
Danksagung erhalten: 77 Mal

Re: Speicher läuft voll

Beitrag von ramses »

Hallo Jimmy

das habe ich bereits gemacht. Das sind nur die Thread's drin die ich auch im Pool habe. Diese werden nicht beendet nur gestoppt und immer wiederverwendet.
Valar Morghulis

Gruss Carlo
Benutzeravatar
Marcus Herz
1000 working lines a day
1000 working lines a day
Beiträge: 851
Registriert: Mo, 16. Jan 2006 8:13
Wohnort: Allgäu
Hat sich bedankt: 39 Mal
Danksagung erhalten: 192 Mal
Kontaktdaten:

Re: Speicher läuft voll

Beitrag von Marcus Herz »

Ich hab die Threads immer neu gemacht. Was ich beim testen merkte, wird ein Thread beendet, wird auch viel Speicher freigegeben. Vielleicht ist das ja ein Lösungsansatz.
Gruß Marcus

Erkenne, was du findest, dann weißt du, wonach du gesucht hast
ramses
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2513
Registriert: Mi, 28. Jul 2010 17:16
Hat sich bedankt: 12 Mal
Danksagung erhalten: 77 Mal

Re: Speicher läuft voll

Beitrag von ramses »

Das Problem beim beenden jedes Thread ist oder war dass sich beim Start eines neuen Thread ab und zu der Hauptthread hängte bezw. abstürzte, was nachher mit dem Threadpool nie mehr geschehen ist ....
Valar Morghulis

Gruss Carlo
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: Speicher läuft voll

Beitrag von AUGE_OHR »

hi Carlos,

da du offensichtlich mit den Threads "jetzt" Probleme hast muss "irgendwas" passieren.
da hilft es nicht wenn es "vorher" (scheinbar) funktioniert hat

ich habe die Frage gestellt weil ich, wie Marcus, festgestellt habe das Thread Speicher "fressen" wenn die nicht "ordentlich" geschlossen werden.
wenn du die Threads "auflisten" lässt und dabei die Threads NIL zeigen sind die NICHT "geschlossen" solange du die "siehst"

---

man kann doch einen Thread "wieder" aufrufen wenn man o:SetInterval() verwendet
wenn ich einen Thread nur 1 x aufrufe ist IHMO o:SetInterval() = "un-endlich"

versuche mal

Code: Alles auswählen

   oThread:setInterval( NIL ) 
   oThread := NIL 
   sleep(1) 
gruss by OHR
Jimmy
ramses
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2513
Registriert: Mi, 28. Jul 2010 17:16
Hat sich bedankt: 12 Mal
Danksagung erhalten: 77 Mal

Re: Speicher läuft voll

Beitrag von ramses »

Hallo Jimmy

ich habe keine geschlossenen Threads weil diese mit Absicht nie geschlossen werden. Die werden pausiert. Die Threadinfos sehen so aus:

Code: Alles auswählen

TotalThreadsExist:  73
         1       988        36  GETTHREADINFO              -> thread
         3      2444      3855  XBSERVER:ACCEPT            -> xbHTTPServer
         4      2508      3855  XBSERVER:ACCEPT            -> xbHTTPServer
         5      2572      5492  XBHTTPTHREAD:EXECUTE       -> xbHTTPThread
         6      2636      5492  XBHTTPTHREAD:EXECUTE       -> xbHTTPThread
         7      2696      5492  XBHTTPTHREAD:EXECUTE       -> xbHTTPThread
         8      2756      5492  XBHTTPTHREAD:EXECUTE       -> xbHTTPThread
         9      2816      5492  XBHTTPTHREAD:EXECUTE       -> xbHTTPThread
        10      2820      5492  XBHTTPTHREAD:EXECUTE       -> xbHTTPThread
        11      2084      5492  XBHTTPTHREAD:EXECUTE       -> xbHTTPThread
        12      2848      5492  XBHTTPTHREAD:EXECUTE       -> xbHTTPThread
        13      3016      3158  XBSOCKET:SSLACCEPT         -> xbHTTPThread
        14      3068      5492  XBHTTPTHREAD:EXECUTE       -> xbHTTPThread
        15      2992      5492  XBHTTPTHREAD:EXECUTE       -> xbHTTPThread
es gibt keine mit NIL

die xbHTTPThread werden vom xbHTTPServer aktiviert. Gerne würde ich die xbHTTPThread's jeweils beenden. Leider dauert es dann gar nicht lange bis das jedesmal neu starten eines "ArbeitThreads" den ServerThread killt.
Valar Morghulis

Gruss Carlo
ramses
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2513
Registriert: Mi, 28. Jul 2010 17:16
Hat sich bedankt: 12 Mal
Danksagung erhalten: 77 Mal

Re: Speicher läuft voll

Beitrag von ramses »

Marcus

hast du nach einigen hundert erstellten PDF's mal den Prozess Explorer genommen und nachgeschaut was für Thread deine App laufen hat?
Bleiben bei dir nicht viele solche wie die unten im Bild markierten Hängen?


combit.jpg
combit.jpg (187.88 KiB) 3716 mal betrachtet
Valar Morghulis

Gruss Carlo
Benutzeravatar
Marcus Herz
1000 working lines a day
1000 working lines a day
Beiträge: 851
Registriert: Mo, 16. Jan 2006 8:13
Wohnort: Allgäu
Hat sich bedankt: 39 Mal
Danksagung erhalten: 192 Mal
Kontaktdaten:

Re: Speicher läuft voll

Beitrag von Marcus Herz »

sind mir nicht aufgefallen. Werd den Test nochmal wiederholen und explizit kontrollieren.
Gruß Marcus

Erkenne, was du findest, dann weißt du, wonach du gesucht hast
Benutzeravatar
Marcus Herz
1000 working lines a day
1000 working lines a day
Beiträge: 851
Registriert: Mo, 16. Jan 2006 8:13
Wohnort: Allgäu
Hat sich bedankt: 39 Mal
Danksagung erhalten: 192 Mal
Kontaktdaten:

Re: Speicher läuft voll

Beitrag von Marcus Herz »

snap.jpg
snap.jpg (79.66 KiB) 3379 mal betrachtet
Ich verwende den procexp64 von Sysinternal. Schaut anders aus als deiner.
Habe mal wieder 320 Threads, max. 80 paralell, 2200 PDFs, gestartet, Am Ende bleibt das im Speicher. Handles und Private Bytes und Working Set sind konstant. Garbage Kollektor braucht aber ca. 10 sec. nach dem Durchlauf (Programm bleibt auf sleep hängen), bis er alles wieder freigegeben hat.
Keine Duplette gefunden
Gruß Marcus

Erkenne, was du findest, dann weißt du, wonach du gesucht hast
Benutzeravatar
Marcus Herz
1000 working lines a day
1000 working lines a day
Beiträge: 851
Registriert: Mo, 16. Jan 2006 8:13
Wohnort: Allgäu
Hat sich bedankt: 39 Mal
Danksagung erhalten: 192 Mal
Kontaktdaten:

Re: Speicher läuft voll

Beitrag von Marcus Herz »

snap1.jpg
snap1.jpg (23.53 KiB) 3376 mal betrachtet
Jetzt hab ich dein Fenster auch entdeckt. Das schaut bei mir dann so aus, Alles clean
Gruß Marcus

Erkenne, was du findest, dann weißt du, wonach du gesucht hast
ramses
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2513
Registriert: Mi, 28. Jul 2010 17:16
Hat sich bedankt: 12 Mal
Danksagung erhalten: 77 Mal

Re: Speicher läuft voll

Beitrag von ramses »

Hallo Marcus
ich habe heute mal durch einen Reg. Key den Legacy Export Modus aktiviert.
Ich nutze in der App nur: JobOpen // PDF-Export // JobClose
Kaum zu glauben sämtliche Probleme sind so beseitigt. 40-50% bessere Performance keine hängenden Threads keine "interne Datenstrukturen zerstört" Meldungen mehr ....... läuft einfach nur perfekt.

Leider gibt dies keine PDF-A Files die zwingend sind. So bleibt es ein Traum: "So sollte es sein". Aber auch schön: es zeigt die Quelle der Probleme.
Valar Morghulis

Gruss Carlo
Benutzeravatar
Wolfgang Ciriack
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2932
Registriert: Sa, 24. Sep 2005 9:37
Wohnort: Berlin
Hat sich bedankt: 13 Mal
Danksagung erhalten: 34 Mal
Kontaktdaten:

Re: Speicher läuft voll

Beitrag von Wolfgang Ciriack »

Das Problem war eigentlich ab Version 26 SP5 behoben ?!?
Viele Grüße
Wolfgang
ramses
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2513
Registriert: Mi, 28. Jul 2010 17:16
Hat sich bedankt: 12 Mal
Danksagung erhalten: 77 Mal

Re: Speicher läuft voll

Beitrag von ramses »

Wolfgang Ciriack hat geschrieben: Fr, 14. Okt 2022 5:50 Das Problem war eigentlich ab Version 26 SP5 behoben ?!?
Die hatte ich in der App nicht im Einsatz. Die lief auf der Version 22 bis die Anforderung nach revisionssicheren PDF/A Files kam.
Und seit der Umstellung hatten wir wirklich eigentlich nur andauernd Probleme ......
L&L war ja auch gar nicht der Verdächtige da es ja *nur* massenhaft Speicherprobleme in der App gab.
Jetzt muss ich das Problem einfach dringend beseitigen.
Die betroffenen Kunden finden es nicht mehr lustig wenn es jeweis den OnLine-Shop platt macht.....
Valar Morghulis

Gruss Carlo
ramses
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2513
Registriert: Mi, 28. Jul 2010 17:16
Hat sich bedankt: 12 Mal
Danksagung erhalten: 77 Mal

Re: Speicher läuft voll [Erledigt]

Beitrag von ramses »

Der Wrapper zum Aufruf der DLL-Funktionen aus Xbase heraus war mir schon immer ein Dorn im Auge ....
Jetzt habe ich Ihn umgeschrieben und die Probleme sind beseitigt.
Valar Morghulis

Gruss Carlo
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Re: Speicher läuft voll [Erledigt]

Beitrag von Tom »

Kannst Du das ein wenig präziser fassen, Carlo?
Herzlich,
Tom
ramses
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2513
Registriert: Mi, 28. Jul 2010 17:16
Hat sich bedankt: 12 Mal
Danksagung erhalten: 77 Mal

Re: Speicher läuft voll [Erledigt]

Beitrag von ramses »

Hallo Tom
gerne.

Geändert habe ich noch die PDF/A Version von 3a auf 2a und zum Test und jetzt im Einsatz ist das Exportmodul 27.005.

Der von Combit mitgelieferte Wrapper lädt die DLL und erstellt die Call-Templates Chaotisch unter umständen über viele Worker Threads des WebServers verteilt lädt er die Call-Templates in viele viele Static Vars.

Ich bin jetzt hingegangen und lade das gezielt früh beim Programmstart mit der Funktion LoadListLabelDLL() // siehe unten // diese erstellt die NUR die in allen meinen Programmen benötigten Templates im MainThread und speichert diese in einem STATIC Array. Gleichzeitig wird auch der "Schutz-Job" oder Dummy Job angelegt. Die zur Laufzeit benötigten Funktionen sind alle Fix und greifen auf das eine Static Array zu.

Eine Erklährung wieso es so funktioniert habe ich keine. Auch nach vielen 10'000 erstellten PDF konnte auch der Web-Stresstest das Servermodul nicht mehr killen. Ich hatte das Problem mit einer anderen DLL schon mal die Funktioniert auch nur mit aufrufen auf diese Art.....

Im folgenden Code sind die wesentlichen Teile. Ein Modulexit oder DLLunload braucht es nicht. (Hoffentlich habe ich nicht zuviel rausgeschnitten)

Code: Alles auswählen

 #include "dll.ch"
 #include "fileio.ch"
 #include "\apps\ListLabelXX\cmbtllXX.ch"
 #include "common.ch"



#define CRLF              (Chr(13)+Chr(10))


#DEFINE LIZENZSTRING   "XXXXXXXXXXXXXXXXXX"
#DEFINE MAIN_DLLNAME   "CMLL27.DLL"



static saCallLL := nil
static hDll     := 0



* ---------------------------------------------------------------------------------
* DLL-Laden
*
*
function LoadListLabelDLL( cVersion )
local ret_val := .t.


        cVersion := ""

        If !LLXXModuleInit()
            logEXEerror( "Error loading " + MAIN_DLLNAME+ " / OS error#"+Alltrim(Str(DosError())) +"/"+DosErrorMessage(DosError())+ CRLF )
            ret_val := .f.
        else
            cVersion := alltrim(str(LlGetVersion(LL_VERSION_MAJOR)))+"."+ alltrim(str(LlGetVersion(LL_VERSION_MINOR)))
        endif
return(ret_val)


static function LLxxModuleInit()

        if hDll == 0
            hDll := DllLoad(MAIN_DLLNAME)
            if ! hDll == 0
                __LLInit()
                LLOpenPrintJob()
            endif
        endif

return(hDll # 0)



//MARKER:MAKELLFUNC
// -------------------------------------------------------------------
//
//  ACHTUNG: Ab hier wird der Code durch makeLLfunc.exe automatisch erstellt --> Es darf nichts ge„ndert  werden !!!
//
// -------------------------------------------------------------------

static  function __LLInit()
   local i, imax
   local aFuncList := {;
     10,;                               // LlJobOpen
     14,;                               // LlGetVersion
     66,;                               // LlSetOptionString
     13,;                               // LlSetDebug
     26,;                               // LlDefineVariableStart
     70,;                               // LlDesignerProhibitAction
     202,;                              // LlViewerProhibitAction
     64,;                               // LlSetOption
     11,;                               // LlJobClose
     31,;                               // LlPreviewSetTempPath
     200,;                              // LlSetPrinterDefaultsDir
     32,;                               // LlPreviewDeleteFiles
     53,;                               // LlPrintStart
     68,;                               // LlPrintSetOptionString
     246,;                              // LlXSetParameter
     248,;                              // LlPrintResetProjectState
     38,;                               // LlPrintEnd
     28,;                               // LlDefineLayout
     19,;                               // LlDefineFieldExt
     23,;                               // LlDefineVariableExt
     59,;                               // LlExprParse
     63,;                               // LlExprEvaluate
     62,;                               // LlExprFree
     35,;                               // LlPrint
     39,;                               // LlPrintFields
     40,;                               // LlPrintFieldsEnd
     219,;                              // LlGetErrortext
     54,;                               // LlPrintWithBoxStart
     77,;                               // LlPrintOptionsDialogTitle
     51,;                               // LlPrintSetOption
     96,;                               // LlGetVariableType
     92,;                               // LlGetVariableContents
     214,;                              // LlProjectOpen
     206,;                              // LlDomGetProject
     209,;                              // LlDomGetObject
     210,;                              // LlDomGetSubobjectCount
     211,;                              // LlDomGetSubobject
     207,;                              // LlDomGetProperty
     208,;                              // LlDomSetProperty
     215,;                              // LlProjectSave
     216,;                              // LlProjectClose
     50,;                               // LlPrintSetBoxText
     56,;                               // LlSelectFileDlgTitleEx
     44,;                               // LlPrintGetRemainingItemsPerTable
     43,;                               // LlPrintGetItemsPerTable
     258,;                              // LlGetUsedIdentifiersEx
     245;                               // LlPrintResetObjectStates
     }


   imax     := Len(aFuncList)
   saCallLL := Array(imax)

   for i := 1 to imax
      saCallLL[i] := DllPrepareCall( hDll, DLL_STDCALL, aFuncList[i] )
   next


return(.t.)




// ---------------------------------------------
function LlJobOpen(nLanguage)
   return(  DllExecuteCall( saCallLL[1], nLanguage) )
// ---------------------------------------------
function LlGetVersion(nCmd)
   return(  DllExecuteCall( saCallLL[2], nCmd) )
// ---------------------------------------------
function LlSetOptionString(hLlJob, nIndex, pszBuffer)
   return(  DllExecuteCall( saCallLL[3], hLlJob, nIndex, @pszBuffer) )
// ---------------------------------------------
procedure LlSetDebug(nOnOff)
   DllExecuteCall( saCallLL[4], nOnOff)
   return
// ---------------------------------------------
procedure LlDefineVariableStart(hLlJob)
   DllExecuteCall( saCallLL[5], hLlJob)
   return
// ---------------------------------------------
function LlDesignerProhibitAction(hLlJob, nMenuID)
   return(  DllExecuteCall( saCallLL[6], hLlJob, nMenuID) )
// ---------------------------------------------
function LlViewerProhibitAction(hLlJob, nMenuID)
   return(  DllExecuteCall( saCallLL[7], hLlJob, nMenuID) )
// ---------------------------------------------
function LlSetOption(hLlJob, nMode, nValue)
   return(  DllExecuteCall( saCallLL[8], hLlJob, nMode, nValue) )
// ---------------------------------------------
procedure LlJobClose(hLlJob)
   DllExecuteCall( saCallLL[9], hLlJob)
   return
// ---------------------------------------------
function LlPreviewSetTempPath(hLlJob, pszPath)
   return(  DllExecuteCall( saCallLL[10], hLlJob, @pszPath) )
// ---------------------------------------------
function LlSetPrinterDefaultsDir(hLlJob, pszDir)
   return(  DllExecuteCall( saCallLL[11], hLlJob, @pszDir) )
// ---------------------------------------------
function LlPreviewDeleteFiles(hLlJob, pszObjName, pszPath)
   return(  DllExecuteCall( saCallLL[12], hLlJob, @pszObjName, @pszPath) )
// ---------------------------------------------
function LlPrintStart(hLlJob, nObjType, pszObjName, nPrintOptions, nReserved)
   return(  DllExecuteCall( saCallLL[13], hLlJob, nObjType, @pszObjName, nPrintOptions, nReserved) )
// ---------------------------------------------
function LlPrintSetOptionString(hLlJob, nIndex, pszBuffer)
   return(  DllExecuteCall( saCallLL[14], hLlJob, nIndex, @pszBuffer) )
// ---------------------------------------------
function LlXSetParameter(hLlJob, nExtensionType, pszExtensionName, pszKey, pszValue)
   return(  DllExecuteCall( saCallLL[15], hLlJob, nExtensionType, @pszExtensionName, @pszKey, @pszValue) )
// ---------------------------------------------
function LlPrintResetProjectState(hJob)
   return(  DllExecuteCall( saCallLL[16], hJob) )
// ---------------------------------------------
function LlPrintEnd(hLlJob, nPages)
   return(  DllExecuteCall( saCallLL[17], hLlJob, nPages) )
// ---------------------------------------------
function LlDefineLayout(hLlJob, hWnd, pszTitle, nObjType, pszObjName)
   return(  DllExecuteCall( saCallLL[18], hLlJob, hWnd, @pszTitle, nObjType, @pszObjName) )
// ---------------------------------------------
function LlDefineFieldExt(hLlJob, pszVarName, lpbufContents, lPara, lpPtr)
   return(  DllExecuteCall( saCallLL[19], hLlJob, @pszVarName, @lpbufContents, lPara, lpPtr) )
// ---------------------------------------------
function LlDefineVariableExt(hLlJob, pszVarName, lpbufContents, lPara, lpPtr)
   return(  DllExecuteCall( saCallLL[20], hLlJob, @pszVarName, @lpbufContents, lPara, lpPtr) )
// ---------------------------------------------
function LlExprParse(hLlJob, lpExprText, bIncludeFields)
   return(  DllExecuteCall( saCallLL[21], hLlJob, @lpExprText, bIncludeFields) )
// ---------------------------------------------
function LlExprEvaluate(hLlJob, lpExpr, pszBuf, nBufSize)
   return(  DllExecuteCall( saCallLL[22], hLlJob, lpExpr, @pszBuf, nBufSize) )
// ---------------------------------------------
procedure LlExprFree(hLlJob, lpExpr)
   DllExecuteCall( saCallLL[23], hLlJob, lpExpr)
   return
// ---------------------------------------------
function LlPrint(hLlJob)
   return(  DllExecuteCall( saCallLL[24], hLlJob) )
// ---------------------------------------------
function LlPrintFields(hLlJob)
   return(  DllExecuteCall( saCallLL[25], hLlJob) )
// ---------------------------------------------
function LlPrintFieldsEnd(hLlJob)
   return(  DllExecuteCall( saCallLL[26], hLlJob) )
// ---------------------------------------------
function LlGetErrortext(nError, pszBuffer, nBufSize)
   return(  DllExecuteCall( saCallLL[27], nError, @pszBuffer, nBufSize) )
// ---------------------------------------------
function LlPrintWithBoxStart(hLlJob, nObjType, pszObjName, nPrintOptions, nBoxType, hWnd, pszTitle)
   return(  DllExecuteCall( saCallLL[28], hLlJob, nObjType, @pszObjName, nPrintOptions, nBoxType, hWnd, @pszTitle) )
// ---------------------------------------------
function LlPrintOptionsDialogTitle(hLlJob, hWnd, pszTitle, pszText)
   return(  DllExecuteCall( saCallLL[29], hLlJob, hWnd, @pszTitle, @pszText) )
// ---------------------------------------------
function LlPrintSetOption(hLlJob, nIndex, nValue)
   return(  DllExecuteCall( saCallLL[30], hLlJob, nIndex, nValue) )
// ---------------------------------------------
function LlGetVariableType(hLlJob, pszName)
   return(  DllExecuteCall( saCallLL[31], hLlJob, @pszName) )
// ---------------------------------------------
function LlGetVariableContents(hLlJob, pszName, pszBuffer, nBufSize)
   return(  DllExecuteCall( saCallLL[32], hLlJob, @pszName, @pszBuffer, nBufSize) )
// ---------------------------------------------
function LlProjectOpen(hLlJob, nObjType, pszObjName, nOpenMode)
   return(  DllExecuteCall( saCallLL[33], hLlJob, nObjType, @pszObjName, nOpenMode) )
// ---------------------------------------------
function LlDomGetProject(hLlJob, phDOMObj)
   return(  DllExecuteCall( saCallLL[34], hLlJob, @phDOMObj) )
// ---------------------------------------------
function LlDomGetObject(hDOMObj, pszName, phDOMSubObj)
   return(  DllExecuteCall( saCallLL[35], hDOMObj, @pszName, @phDOMSubObj) )
// ---------------------------------------------
function LlDomGetSubobjectCount(hDOMObj, pnCount)
   return(  DllExecuteCall( saCallLL[36], hDOMObj, @pnCount) )
// ---------------------------------------------
function LlDomGetSubobject(hDOMObj, nPosition, phDOMSubObj)
   return(  DllExecuteCall( saCallLL[37], hDOMObj, nPosition, @phDOMSubObj) )
// ---------------------------------------------
function LlDomGetProperty(hDOMObj, pszName, pszBuffer, nBufSize)
   return(  DllExecuteCall( saCallLL[38], hDOMObj, @pszName, @pszBuffer, nBufSize) )
// ---------------------------------------------
function LlDomSetProperty(hDOMObj, pszName, pszValue)
   return(  DllExecuteCall( saCallLL[39], hDOMObj, @pszName, @pszValue) )
// ---------------------------------------------
function LlProjectSave(hLlJob, pszObjName)
   return(  DllExecuteCall( saCallLL[40], hLlJob, @pszObjName) )
// ---------------------------------------------
function LlProjectClose(hLlJob)
   return(  DllExecuteCall( saCallLL[41], hLlJob) )
// ---------------------------------------------
function LlPrintSetBoxText(hLlJob, szText, nPercentage)
   return(  DllExecuteCall( saCallLL[42], hLlJob, @szText, nPercentage) )
// ---------------------------------------------
function LlSelectFileDlgTitleEx(hLlJob, hWnd, pszTitle, nObjType, pszObjName, nBufSize, pReserved)
   return(  DllExecuteCall( saCallLL[43], hLlJob, hWnd, @pszTitle, nObjType, @pszObjName, nBufSize, pReserved) )
// ---------------------------------------------
function LlPrintGetRemainingItemsPerTable(hLlJob, pszField)
   return(  DllExecuteCall( saCallLL[44], hLlJob, @pszField) )
// ---------------------------------------------
function LlPrintGetItemsPerTable(hLlJob)
   return(  DllExecuteCall( saCallLL[45], hLlJob) )
// ---------------------------------------------
function LlGetUsedIdentifiersEx(hLlJob, pszProjectName, nIdentifierTypes, pszBuffer, nBufSize)
   return(  DllExecuteCall( saCallLL[46], hLlJob, @pszProjectName, nIdentifierTypes, @pszBuffer, nBufSize) )
// ---------------------------------------------
function LlPrintResetObjectStates(hLlJob)
   return(  DllExecuteCall( saCallLL[47], hLlJob) )
// ---------------------------------------------

Valar Morghulis

Gruss Carlo
Benutzeravatar
Marcus Herz
1000 working lines a day
1000 working lines a day
Beiträge: 851
Registriert: Mo, 16. Jan 2006 8:13
Wohnort: Allgäu
Hat sich bedankt: 39 Mal
Danksagung erhalten: 192 Mal
Kontaktdaten:

Re: Speicher läuft voll [Erledigt]

Beitrag von Marcus Herz »

Der von Combit mitgelieferte Wrapper lädt die DLL und erstellt die Call-Templates Chaotisch unter umständen über viele Worker Threads des WebServers verteilt lädt er die Call-Templates in viele viele Static Vars.
STATIC Variablen sind doch nicht Threadgebunden? Egal, in welchem Thread ich auf eine STATIC zugreife, es ist immer derselbe Speicher?
Die Anzahl STATICs sollte doch kein Problem darstellen.
Das klingt aber jetzt ganz anders.
Was macht dann den Unterschied, dass es jetzt stabil laüft, ein Template in einem STATIC in einer Funktion oder in einem Array Element?

In AdsClass hab ich die Templates auch alle in einem STATIC Array abgelegt.
Und lade alle Templates beim Start. Das geht schnell. So wie du das jetzt machst. Und AdsClass ist stabil.

Templates im Array sind jedenfalls schneller, wie jedesmal die Funktion aufzurufen und dort das STATIC auszulösen.

Noch zuviele offene Fragen für mich...
Gruß Marcus

Erkenne, was du findest, dann weißt du, wonach du gesucht hast
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Re: Speicher läuft voll [Erledigt]

Beitrag von Tom »

Hallo, Carlo.

Danke für die Ausführungen und den Code. Ich mache das eigentlich schon immer so (bis auf den Dummy-Job), aber bezüglich Deiner Erläuterungen zu den STATIC-Arrays muss ich mich Marcus anschließen - das ist nicht wirklich schlüssig. Aber Du sagst ja selbst, dass Du nicht genau den Finger auf die Wunde legen kannst, die jetzt geschlossen ist. Mmh ...
Herzlich,
Tom
ramses
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2513
Registriert: Mi, 28. Jul 2010 17:16
Hat sich bedankt: 12 Mal
Danksagung erhalten: 77 Mal

Re: Speicher läuft voll [Erledigt]

Beitrag von ramses »

Tom hat geschrieben: Do, 20. Okt 2022 10:11 Aber Du sagst ja selbst, dass Du nicht genau den Finger auf die Wunde legen kannst, die jetzt geschlossen ist. Mmh ...
Hallo Tom
vielleicht entsteht durch die änderung die Wunde einfach nicht mehr. Das frühere Exportmodul das ohne Problem lief war in Delphi geschrieben das neue in C++ . Das neue stelle ganz andere Anforderungen und geht anders mit dem Speicher um.
Sicher möchte ich auch eine Erklährung und möchte auch wissen wieso das so ist.
Aber uns ist jetzt wichtig das der Speicher nicht mehr vollläuft und das Programm zum Hänger macht. Das nehmen wir natürlich noch so gerne auch ohne Erklährung .....
Valar Morghulis

Gruss Carlo
Antworten