In the trivial code below I am crating a linked list of buffers. At first I was thinking that the limit on the number of allocated elements depends on the available RAM memory (in 32bit address space). To my surprise, the BBox environment started "yelling" at me when the number of allocated buffers was (it varies a bit):
Num elements in the list= 316623
Num of allocated bytes= 666174792
There some questions:
1. Why we cannot go beyond a list that can store more than let say 1GB worth of data?
2. When the garbage collector should claim all the memory back? After assignments
First := NIL;
Head := NIL;
CurrEl := NIL;
the environment still showed allocated memory around 670_000_000 bytes. Only unloading the module reclaim the memory. In addition, the Win7 Task Manager shows more than 674_000_000 bytes allocated to the BBox even if internally the heap is at level of ~500k.
BTW , does anybody has any experience with using a DLL from BBox that starts a task (let say an asynchronous process) , and still is able to communicate with a program written in CP ?
Cheers,
Darek
Code: Select all
MODULE dmTestsTestList;
IMPORT
Log := StdLog;
CONST
BuffSize = 2100;
TYPE
tData* = ARRAY BuffSize OF BYTE;
tPtrNode = POINTER TO tNode;
tNode = RECORD
Buffer*: tData;
Next: tPtrNode;
END; (* record *)
VAR
First, Head, CurrEl: tPtrNode;
NumElemCnt: INTEGER;
RetriveFirstElem: BOOLEAN;
(* -------------------------------------------------------------------------------------------------------------------------------------------- *)
PROCEDURE Init* ();
BEGIN
NumElemCnt := 0;
RetriveFirstElem := FALSE;
First := NIL; Head := NIL; CurrEl := NIL;
Log.String("Node size is: "); Log.Int(SIZE(tNode)); Log.Ln();
END Init;
(* -------------------------------------------------------------------------------------------------------------------------------------------- *)
PROCEDURE StoreData* (v: tData);
BEGIN
IF NumElemCnt = 0 THEN
NEW(CurrEl);
IF CurrEl = NIL THEN
HALT(100);
END;
First := CurrEl;
Head := CurrEl;
CurrEl.Buffer := v;
CurrEl.Next := NIL;
INC(NumElemCnt);
ELSE
NEW(CurrEl);
IF CurrEl = NIL THEN
Log.Ln(); Log.String("Num elements in the list="); Log.Int(NumElemCnt); Log.Ln();
Log.String("Num of allocated bytes="); Log.Int(NumElemCnt * SIZE(tNode)); Log.Ln();
HALT(100);
END;
CurrEl.Buffer := v;
CurrEl.Next := NIL;
Head.Next := CurrEl;
Head := CurrEl;
INC(NumElemCnt);
END; (* if *)
END StoreData;
(* -------------------------------------------------------------------------------------------------------------------------------------------- *)
PROCEDURE IsEmpty* (): BOOLEAN;
BEGIN
RETURN (Head = NIL);
END IsEmpty;
(* -------------------------------------------------------------------------------------------------------------------------------------------- *)
PROCEDURE RetriveData* (VAR v: tData);
BEGIN
IF ~RetriveFirstElem THEN
Head := First;
v := Head.Buffer;
Head := Head.Next;
RetriveFirstElem := TRUE;
First := NIL (* added for testing *)
ELSE
IF Head # NIL THEN
v := Head.Buffer;
Head := Head.Next;
END;
END; (* if *)
END RetriveData;
(* -------------------------------------------------------------------------------------------------------------------------------------------- *)
PROCEDURE GetNumElements* (): INTEGER;
BEGIN
RETURN(NumElemCnt);
END GetNumElements;
(* -------------------------------------------------------------------------------------------------------------------------------------------- *)
PROCEDURE RunTest*;
CONST
NumFiles = 500000;
VAR
i: INTEGER;
data: tData;
BEGIN
Init();
Log.String("Adding data to the list ...");
FOR i := 0 TO LEN(data) - 1 DO data[i] := 1; END;
FOR i := 1 TO NumFiles DO
StoreData(data);
END; (* for *)
Log.String("done."); Log.Ln();
Log.String("Num elements in the list"); Log.Int(GetNumElements()); Log.Ln();
WHILE ~IsEmpty() DO
RetriveData(data);
END; (* while *)
First := NIL;
Head := NIL;
CurrEl := NIL;
Log.String("DONE "); Log.Ln();
END RunTest;
(* -------------------------------------------------------------------------------------------------------------------------------------------- *)
BEGIN
END dmTestsTestList.
dmTestsTestList.RunTest
DevDebug.Unload dmTestsTestList