Avatar billede kokoko Nybegynder
23. oktober 2000 - 22:39 Der er 4 kommentarer og
2 løsninger

EStackOverflow

Som jeg har forstået det så får man en EStackOverflow når der er for mange data til at ens program kan følge med, ik?
Det eneste sted i mit program hvor jeg tror det kan gå galt er når jeg skal behandle de data jeg modtager via sockets... lyder det ikke også som der?
Nå men jeg skal jo have fundet en løsning på det problem og så tænkte jeg om det var muligt at smide alt data over i en TStringList og så have en timer til at kører den igennem linje for linje... er det en god ide eller er der nogen der har en bedre?
Avatar billede sjensen Nybegynder
24. oktober 2000 - 08:37 #1
EStackOverflow kommer bl.a. når man i en procedure definerer vars der ikke er plads til i maskinens hukommelse. Dette sker meget sjældent og ses oftes når man f.eks. kalder en procedure/funktion hvor man opretter en var (med create) men glemmer at slette (med free) den igen, eller når man laver rekursive kald, d.v.s. kalder proceduren fra proceduren selv.

Jeg ville derfor starte med at checke at alle \"creates\" bliver \"free\"\'et inden proceduren/funktionen forlades.

Med hensyn til Stringlist: Ja, hvorfor ikke. Prop de data du vil ind i slutningen og lad en timer løbe den igennem i et fast interval, og evt. slette linier fra toppen.

Jeg er ikke helt sikker på hvilket program du henviser til, men generelt er det en god ide at have en rutine der modtager data uafhængigt af hvad programmet i øvrigt laver (f.eks. via en interrupt som med en seriel port) og så bruge en timer til regelmæssigt at gennemgå de modtagne data. Det er sådan jeg håndtere indkomne data via serielle porte og jeg mister alrdig data, selvom programmet er i gang med noget andet tidskrævende.
Avatar billede delphidaner Nybegynder
24. oktober 2000 - 09:47 #2
Ville det ikke være smartere at bruge en thread i stedet for en timer?
Avatar billede borrisholt Novice
24. oktober 2000 - 10:19 #3
Eller en timer lavet i en tråd ?

jens B
Avatar billede kokoko Nybegynder
24. oktober 2000 - 13:17 #4
sjensen: jeg tjekker lige de ting du har sagt, men jeg mener nu jeg har tjekket det til hudløshed..

mit program modtager data fra internettet via et tcpip... og den skal kører rigtig mange linje kode igennem hver gang den modtager noget.. men jeg ved ikke om det vil være nogen fordel at bruge en tråd fremfor en timer?!

Avatar billede pellelil Nybegynder
24. oktober 2000 - 13:36 #5
sjensen> Når du siger \"opretter en var (med create)\" så læser jeg det som en variable \"på baggrund af\" en class og i såfald så taler vi kun om 4 bytes da dette er hvad en pointer fylder. Naturligvis bruger du mere hukommelse en 4 bytes til selve classesn, men \"var\'en\" er kun en pointer (selvom den ikke ser sådan ud). Ingen tvivl om at en create \"i løkke der løber løs\" vil bruge alt hukommelse men ikke på stacken.

Du har derimod ganske ret med din kommentar vedr. rekursive procedure/functionen.

En anden mulighed kunne også være procedure/funktioner hvor man bruger \"store parameter\". Hvis man eksempelvis opretter en type som: \"Str255 = String[255];\" så vil denne ALTID fylde 256 bytes på stacken hvorimod en \"String\" kun vil fylde 4.

delphidaner> En tråd vil altid være mere attraktiv end en timer. Du får mere udnyttelse af CPUen med en Thread, hvor en timer vil \"brænde mere CPU tid af\" (dog er det nogle gange en \"akedemisk betragtning\" som ikke betyder noget).

kokoko> Det har ikke noget med \"for mange data\" at gøre. Det er (for at være nøjagtig): \"for mange data på stacken\". Efter som du ikke har beskrevet hvad det er du vil gøre med de data du modtager ej heller hvad det er for nogle data (variabel/fast størrelse, filer, \"telegrammer\"). Men som udgangs punkt så vil jeg sige at hvis du ikke har noget imod at dykke ned i det så vil jeg foreslå at du bruger en ringbuffer (lige som man gjorde i de gode gamle dage). Dette ene og alene fra et perfomance synspunk da du ikke spilder tid med at allokere og deallokere hukommelse (hele bufferen allokeres når du starter og deallokeres når du er færdig).

En ring buffer er et simpelt array (f.eks. \"RingBuffer : Array[0..1023] of char;\". Du skal således have 2 \"pegere\", der henholdsvis peger på det først og det sidste tegn i bufferen. Til at starte med vil din \"Start\" og din \"Stop\" begge pege på element nummer 0 (definer dem som Interger). Hvis du læser 25 tegn, så vil din start stadig være 0, men din stop vil være 25. Når du læser (fjerne tegn) fra bufferen så føres dette ved at tælle din \"Start\" værdi op. Navnet \"RingBuffer\" kommer til sin ret når du når hen til enden af bufferen, for så vil du evt ende op med at din start værdi ligger omkring 1015 hvor i mod din stop værdi måske er 5. Dette indikere således at de tegn som du har i bufferen (som endnu ikke er læst) befinder sig i de sidste tegn 1015-1023 og de der befinder sig fra 0-5.

Det kan da godt ske at det \"lyder langhåret\", men det er nok det hurtigste du kan gøre, og hvis det skal lavet i en tråd så er det kun mens du tæller Start og Stop op det er nødvendigt at synkronisere. Mon ikke en god gammel programmerings bog (med respekt for sig selv) indeholder omlysninger om en ringbuffer.
Avatar billede lrj Nybegynder
24. oktober 2000 - 22:04 #6
Mistænker du problemet for at være relateret til lækage i programmet kan jeg varmt anbefale programmet MemProof - http://www.totalqa.com/downloads/memproof.asp - programmet er Gratis(!) og virker til Delphi 2-5 og C++Builder 1-5. Det fortæller dig alt hvad dit program har allokeret mens det har kørt, og hvis du ikke har fået freed dine ressourcer, får du at vide hvor du har allokeret dem.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester