View statistics of memory usage
- Michael Vogel
- Addict
- Posts: 2797
- Joined: Thu Feb 09, 2006 11:27 pm
- Contact:
View statistics of memory usage
Is there a possibility to enhance the debugging tools in the IDE to show the memory usage for specific arrays, lists, images etc.? Even a summarization of theses values could be helpful to get a better feeling about the of the memory consumption.
- Michael Vogel
- Addict
- Posts: 2797
- Joined: Thu Feb 09, 2006 11:27 pm
- Contact:
Re: View statistics of memory usage
I'll to track a program to see, where it grabs all the memory which is seen in the task manager - around 300 MB in my case. I'd like to display a panel which shows the amount of memory for certain resources (images etc.) and arrays, but how to check that easily?
The following code is a first attempt for showing the memory usage of arrays. It does not work properly, and I was (also) wondering, that the protected array 'C' will be seen on the same memory place...
The following code is a first attempt for showing the memory usage of arrays. It does not work properly, and I was (also) wondering, that the protected array 'C' will be seen on the same memory place...
Code: Select all
DataSection
start:
Data.i $555555
EndDataSection
Structure BType
l.l
s.s
i.i
EndStructure
Global Dim A.i(10000)
Global Dim B.BType(10000)
Procedure ShowMem()
Protected Dim C.l(10000)
Protected s=?Start
Protected a=@A
Protected b=@B
Protected c=@C
Protected a0,an
Protected b0,bn
Protected c0,cn
a0=@A(0)
an=@A(ArraySize(A()))
b0=@B(0)
bn=@B(ArraySize(B()))
c0=@C(0)
cn=@C(ArraySize(C()))
Debug "S: "+Hex(s)
Debug "A: "+ Hex(a)+ " ("+ Str(a-s)+ ")"
Debug "B: "+ Hex(b)+ " ("+ Str(b-a)+ ")"
Debug "C: "+ Hex(c)+ " ("+ Str(c-b)+ ")"
Debug "A* "+ Hex(a0)+ " - "+ Hex(an)+ " > "+ Str(an-a0)
Debug "B* "+ Hex(b0)+ " - "+ Hex(bn)+ " > "+ Str(bn-b0)
Debug "C* "+ Hex(c0)+ " - "+ Hex(cn)+ " > "+ Str(cn-c0)
Debug ""
FreeArray(C())
EndProcedure
ShowMem()
ReDim A(20000)
For i=0 To 9999
B(i)\s=RSet("",100,"*")
Next i
Global Dim D(10000)
ShowMem()
Re: View statistics of memory usage
Here are some changes to your ShowMem() code:
The placement of memory for the DataSection is not in any particular relationship to the variable data and so is not of any real value in determining memory used by variables. I tally the size of string memory used by each element in array b(). This tally includes an assumed Null and accommodates ASCII/Unicode differences.
I hope these changes have helped you a bit further.
Code: Select all
Procedure ShowMem()
Protected Dim c.l(10000)
Protected s=?Start
Protected a=@a
Protected b=@b
Protected c=@c
Protected a0,an
Protected b0,bn
Protected c0,cn
Protected i, a_el, b_el, c_el, b_as, b_s
a0=@a(0)
an=@a(ArraySize(a()))
b0=@b(0)
bn=@b(ArraySize(b()))
c0=@c(0)
cn=@c(ArraySize(c()))
a_el = ArraySize(a()) + 1
b_el = ArraySize(b()) + 1
c_el = ArraySize(c()) + 1
b_as = ArraySize(b())
For i = 0 To b_as
b_s + Len(b(i)\s)
Next
b_s = (b_s + b_el) * SizeOf(Character) ;add memory for string nulls on each element, assumes there are no Null strings.
Debug "S: "+Hex(s)
Debug "A: "+ Hex(a)+ " ("+ Str(SizeOf(a))+ ")"
Debug "B: "+ Hex(b)+ " ("+ Str(SizeOf(b))+ ")"
Debug "C: "+ Hex(c)+ " ("+ Str(SizeOf(b))+ ")"
Debug "A* "+ Hex(a0)+ " - "+ Hex(an)+ " > "+ Str(a_el * SizeOf(Integer))
Debug "B* "+ Hex(b0)+ " - "+ Hex(bn)+ " > "+ Str(b_el * SizeOf(BType))
Debug "C* "+ Hex(c0)+ " - "+ Hex(cn)+ " > "+ Str(c_el * SizeOf(Long))
Debug "B*s "+ Str(b_el * SizeOf(BType)) + " + " + Str(b_s) + " > " + Str((b_el * SizeOf(BType)) + b_s)
FreeArray(c())
EndProcedure
I hope these changes have helped you a bit further.
- Michael Vogel
- Addict
- Posts: 2797
- Joined: Thu Feb 09, 2006 11:27 pm
- Contact:
Re: View statistics of memory usage
Thanks,
I will do my best to find an easy way for showing the memory usage for all my different arrays and lists in my program, of course most of them use complex structures with strings and more...
For checking the images memory hunger, I am using these lines now:
I will do my best to find an easy way for showing the memory usage for all my different arrays and lists in my program, of course most of them use complex structures with strings and more...
For checking the images memory hunger, I am using these lines now:
Code: Select all
z=0
For i=0 To #LastImage
If IsImage(i)
n=ImageDepth(i,#PB_Image_InternalDepth)>>3*ImageWidth(i)*ImageHeight(i)
z+n
Debug Str(i)+" "+Str(n)+"bytes, total "+Str(z>>10)+"K"
EndIf
Next i
- Michael Vogel
- Addict
- Posts: 2797
- Joined: Thu Feb 09, 2006 11:27 pm
- Contact:
Re: View statistics of memory usage
Here's another approach to check the actual code, needs to insert one (or more) Memory call(s) in each procedure and will show the memory changes while the program is running...
Code: Select all
; Define Memory
#MS_WindowName="Memory Watcher"
#MS_Window=4999
#MS_Gadget=4999
#MS_X=360
#MS_Y=600
#MS_LineNumber=0
#MS_Yellow=1000000
#MS_Orange=5000000
Global MS_PID.l
Global MS_Name.s
Global MS_Buffer.i
Global MS_NextMemory.i
Global MS_Memory.i
Global MS_Proc.s
Global MS_Line.i
Global MS_Count.i=-1
Global MS_Start.i=ElapsedMilliseconds()
Enumeration
#MS_Time
#MS_Code
#MS_Name
#MS_Memory
#MS_Delta
EndEnumeration
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#TH32CS_SNAPPROCESS=$2
Structure PROCESSENTRY32s
dwsize.l
cntusage.l
th32ProcessID.l
th32DefaultHeapID.l
th32ModuleID.l
cntThreads.l
th32ParentProcessID.l
pcPriClassBase.l
dwFlags.l
szExeFile.s{1024}
EndStructure
Prototype.l GetProcessMemoryInfo_(hProcess.l, *p, cb.l)
Structure PROCESS_MEMORY_COUNTERS
cb.l
PageFaultCount.l
PeakWorkingSetSize.l
WorkingSetSize.l
QuotaPeakPagedPoolUsage.l
QuotaPagedPoolUsage.l
QuotaPeakNonPagedPoolUsage.l
QuotaNonPagedPoolUsage.l
PagefileUsage.l
PeakPagefileUsage.l
EndStructure
; EndDefine
Procedure.s MemoryStr(i.i)
Protected s.s=Str(i)
Protected minus.i
If i<0
minus=1
EndIf
i=Len(s)
While i>3+minus
i-3
s=InsertString(s,".",i+1)
Wend
ProcedureReturn s
EndProcedure
Procedure Memory_Events(time)
time+ElapsedMilliseconds()
While WaitWindowEvent(1)
If ElapsedMilliseconds()>time
Break
EndIf
Wend
EndProcedure
Procedure Memory_Text(pos,s.s,column)
If GetGadgetItemText(#MS_Gadget,pos,column)<>s
SetGadgetItemText(#MS_Gadget,pos,s,column)
EndIf
EndProcedure
Procedure MemoryInit()
Protected MS_Handle.l
Protected MS_Return.l
Protected lvm.LV_COLUMN
OpenWindow(#MS_Window,0,0,#MS_X,#MS_Y,#MS_WindowName)
ListIconGadget(#MS_Gadget,0,0,#MS_X,#MS_Y,"Time",60,#PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect)
AddGadgetColumn(#MS_Gadget,#MS_Code,"Code",60)
AddGadgetColumn(#MS_Gadget,#MS_Name,"Name",80)
AddGadgetColumn(#MS_Gadget,#MS_Memory,"Memory",80)
AddGadgetColumn(#MS_Gadget,#MS_Delta,"Delta",80)
lvm\mask=#LVCF_FMT
lvm\fmt=#LVCFMT_RIGHT
SendMessage_(GadgetID(#MS_Gadget),#LVM_SETCOLUMN,#MS_Code,@lvm)
SendMessage_(GadgetID(#MS_Gadget),#LVM_SETCOLUMN,#MS_Memory,@lvm)
SendMessage_(GadgetID(#MS_Gadget),#LVM_SETCOLUMN,#MS_Delta,@lvm)
StickyWindow(#MS_Window,#True)
MS_Handle=FindWindow_ (0,#MS_WindowName)
MS_Return=GetWindowThreadProcessId_(MS_Handle,@MS_PID)
Memory_Events(10)
ProcedureReturn MS_Return
EndProcedure
Procedure.l MemoryUsage(PID.l)
Protected pmc.PROCESS_MEMORY_COUNTERS
Protected hProcess.l=OpenProcess_(#PROCESS_QUERY_INFORMATION|#PROCESS_VM_READ,#False,PID)
Protected *F
Protected Memory
If OpenLibrary(0,"PSAPI.DLL")
*F=GetFunction(0,"GetProcessMemoryInfo")
If *F
CallFunctionFast(*F,hProcess,@pmc,SizeOf(pmc))
Memory=pmc\WorkingSetSize
Else
CloseLibrary(0)
End
EndIf
Else
End
EndIf
ProcedureReturn Memory
EndProcedure
Procedure MemoryShow(Name.s="",wait=0)
Protected Memory.i
Protected Time.i=ElapsedMilliseconds()-MS_Start
Protected Temp.s
Memory=MemoryUsage(MS_PID)
If MS_Name=MS_Proc+Name
If MS_Buffer=0
MS_Buffer=MS_Memory
EndIf
Else
MS_Count+1
MS_Name=MS_Proc+Name
MS_Buffer=0
MS_Memory=MS_NextMemory
AddGadgetItem(#MS_Gadget,MS_Count,"")
EndIf
If #MS_LineNumber
Temp=Str(MS_Line)
Else
Temp=MS_Proc
EndIf
Memory_Text(MS_Count,FormatDate("%ii:%ss.",Time/1000)+RSet(Str(Time%1000),3,"0"),#MS_Time)
Memory_Text(MS_Count,Temp,#MS_Code)
Memory_Text(MS_Count,Name,#MS_Name)
Memory_Text(MS_Count,MemoryStr(Memory),#MS_Memory)
MS_NextMemory=Memory
If MS_Buffer
Time=Memory-MS_Buffer
Else
Time=Memory-MS_Memory
EndIf
Memory_Text(MS_Count,MemoryStr(Time),#MS_Delta)
If Time>#MS_Orange
SetGadgetItemColor(#MS_Gadget,MS_Count,#PB_Gadget_BackColor,$A0D0FF,#MS_Delta)
ElseIf Time>#MS_Yellow
SetGadgetItemColor(#MS_Gadget,MS_Count,#PB_Gadget_BackColor,$A0FFFF,#MS_Delta)
EndIf
EndProcedure
Macro Memory(x="",w=0)
MS_Line=#PB_Compiler_Line
MS_Proc=#PB_Compiler_Procedure
MemoryShow(x,w)
EndMacro
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; ~~ D E M O ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Procedure TestProcedure()
Memory("A")
Structure TestType
buffer.i [2500]
EndStructure
Protected NewList TestList.TestType()
For i=0 To 999
Memory("Add Element")
AddElement(TestList())
If i%100=0
Memory_Events(5)
EndIf
Next i
Memory("Exit")
EndProcedure
MemoryInit()
Memory("Start",10)
TestProcedure()
TestProcedure()
Memory("All Done")
Repeat
Memory("‹Press Key›")
Until WaitWindowEvent()=#WM_CHAR
Re: View statistics of memory usage
Michael, your code seems to show wrong memory numbers, "virtual memory" is not included.
- Michael Vogel
- Addict
- Posts: 2797
- Joined: Thu Feb 09, 2006 11:27 pm
- Contact:
Re: View statistics of memory usage
Not sure, what virtual memory means (and how to show the information), sorry.Puffolino wrote:Michael, your code seems to show wrong memory numbers, "virtual memory" is not included.