Page 1 of 2 12 LastLast
Results 1 to 10 of 12

Thread: Memory information

  1. #1
    Super Moderator Petr Schreiber's Avatar
    Join Date
    Aug 2005
    Location
    Brno - Czech Republic
    Posts
    7,128
    Rep Power
    732

    Memory information

    Hi,

    please find very simple utility below. It serves to display current memory occupation.
    I probably won't won a prize for coding skills 2006/2007 but it can be useful to see how much your ( or anybody else ) program "eats" the memory. Especially web browsers show interesting info sometimes ...

    I recommend to put a shortcut on the desktop to be able to check it anytime.

    [code=thinbasic] ' Basic info about memory occupation
    ' Useful to see leaks other ar your programs do

    TYPE MEMORYSTATUS
    dwLength AS DWORD
    dwMemoryLoad AS DWORD
    dwTotalPhys AS DWORD
    dwAvailPhys AS DWORD
    dwTotalPageFile AS DWORD
    dwAvailPageFile AS DWORD
    dwTotalVirtual AS DWORD
    dwAvailVirtual AS DWORD
    END TYPE

    DECLARE function GlobalMemoryStatus LIB "KERNEL32.DLL" ALIAS "GlobalMemoryStatus" (lpBuffer AS MEMORYSTATUS) as long

    dim lpBuffer AS MEMORYSTATUS

    GlobalMemoryStatus (lpBuffer)

    msgBox 0, "Physical memory:"+ $CRLF + _
    "Available"+$TAB+FORMAT$(lpBuffer.dwAvailPhys/1024/1024, "0")+" MB"+ $CRLF + _
    "Installed"+$TAB+FORMAT$(lpBuffer.dwTotalPhys/1024/1024, "0")+" MB"+ $CRLF + _
    $CRLF + _
    "Virtual memory:"+ $CRLF + _
    "Available"+$TAB+FORMAT$(lpBuffer.dwAvailVirtual/1024/1024, "0")+" MB"+ $CRLF + _
    "Installed"+$TAB+FORMAT$(lpBuffer.dwTotalVirtual/1024/1024, "0")+" MB"+ $CRLF + _
    $CRLF + _
    "General:"+ $CRLF + _
    "Load"+$TAB+FORMAT$(lpBuffer.dwMemoryLoad, "0")+" %"+ $CRLF _
    , %MB_OK or %MB_ICONINFORMATION, "Memory information"


    [/code]

    Bye,
    Petr
    Learn 3D graphics with ThinBASIC, learn TBGL!
    Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB

  2. #2

    Re: Memory information

    Hi Petr,

    very usefull, in my box with MS Outlook an IExplore opened I have a memory payload of 51%!

    Thanks,
    Roberto
    http://www.thinbasic.com

  3. #3
    thinBasic author ErosOlmi's Avatar
    Join Date
    Sep 2004
    Location
    Milan - Italy
    Age
    57
    Posts
    8,777
    Rep Power
    10

    Re: Memory information

    Thanks Petr. Nice API interface test.
    www.thinbasic.com | www.thinbasic.com/community/ | help.thinbasic.com
    Windows 10 Pro for Workstations 64bit - 32 GB - Intel(R) Xeon(R) W-10855M CPU @ 2.80GHz - NVIDIA Quadro RTX 3000

  4. #4
    Super Moderator Petr Schreiber's Avatar
    Join Date
    Aug 2005
    Location
    Brno - Czech Republic
    Posts
    7,128
    Rep Power
    732

    Re: Memory information

    Hi,

    thanks for reactions. Now comes more interesting sample - featuring progressbars and timer.
    It is very interesting to see, how the free memory is getting loaded for example at startup of the Windows. On my box I start at 166 of 319 and end at 134 of 319 MB. Terrible

    Hope you'll find it more interesting as it is refreshed every second.
    The code is compilation of few "SampleScripts".

    [code=thinbasic] ' Basic info about memory occupation
    ' Version 2.0 - visual presentation, updated every second !

    uses "UI"

    DIM hDlg AS DWORD
    dim Msg, wparam,lparam as dword

    TYPE MEMORYSTATUS
    dwLength AS DWORD
    dwMemoryLoad AS DWORD
    dwTotalPhys AS DWORD
    dwAvailPhys AS DWORD
    dwTotalPageFile AS DWORD
    dwAvailPageFile AS DWORD
    dwTotalVirtual AS DWORD
    dwAvailVirtual AS DWORD
    END TYPE

    DECLARE function GlobalMemoryStatus LIB "KERNEL32.DLL" ALIAS "GlobalMemoryStatus" (lpBuffer AS MEMORYSTATUS) as long
    DECLARE FUNCTION KillTimer LIB "USER32.DLL" ALIAS "KillTimer" (BYVAL hWnd AS DWORD, BYVAL nIDEvent AS LONG) AS LONG
    DECLARE FUNCTION SetTimer LIB "USER32.DLL" ALIAS "SetTimer" (BYVAL hWnd AS DWORD, BYVAL nIDEvent AS LONG, BYVAL uElapse AS DWORD, BYVAL lpTimerFunc AS LONG) AS LONG

    global lpBuffer AS MEMORYSTATUS

    %ID_TIMER = 5000

    %PROG_BAR_1 = 1001
    %PROG_BAR_2 = 1002
    %PROG_BAR_3 = 1003
    global hProgress1 as dword
    global hProgress2 as dword
    global hProgress3 as dword

    DIALOG NEW 0, "Memory guardian", 0, 0, 210, 100, _
    %WS_DLGFRAME OR %WS_CAPTION OR %WS_SYSMENU, _
    %WS_EX_TOPMOST TO hDlg

    CONTROL ADD LABEL, hDlg, 1000,"Physical memory", 5, 5, 200, 14
    CONTROL ADD "msctls_progress32", hDlg, %PROG_BAR_1, "", 5, 20, 200, 10, %WS_CHILD OR %WS_VISIBLE OR %PBS_SMOOTH
    CONTROL HANDLE hDlg, %PROG_BAR_1 TO hProgress1

    CONTROL ADD LABEL, hDlg, 2000,"Virtual memory", 5, 35, 200, 14
    CONTROL ADD "msctls_progress32", hDlg, %PROG_BAR_2, "", 5, 50, 200, 10, %WS_CHILD OR %WS_VISIBLE OR %PBS_SMOOTH
    CONTROL HANDLE hDlg, %PROG_BAR_2 TO hProgress2

    CONTROL ADD LABEL, hDlg, 3000,"Total load", 5, 65, 200, 14
    CONTROL ADD "msctls_progress32", hDlg, %PROG_BAR_3, "", 5, 80, 200, 10, %WS_CHILD OR %WS_VISIBLE OR %PBS_SMOOTH
    CONTROL HANDLE hDlg, %PROG_BAR_3 TO hProgress3

    GlobalMemoryStatus (lpBuffer)
    SetTimer hDlg, %ID_TIMER, 1000, %NULL
    ProgressBar_SetRange32 (hProgress1, 0, lpBuffer.dwTotalPhys)
    ProgressBar_SetPos (hProgress1, 50)
    ProgressBar_SetBarColor (hProgress1, rgb(0,128,0))
    ProgressBar_SetBkColor (hProgress1, rgb(128,0,0))

    ProgressBar_SetRange32 (hProgress2, 0, lpBuffer.dwTotalVirtual)
    ProgressBar_SetPos (hProgress2, 25)
    ProgressBar_SetBarColor (hProgress2, rgb(0,128,0))
    ProgressBar_SetBkColor (hProgress2, rgb(128,0,0))

    ProgressBar_SetRange32 (hProgress3, 0, 100)
    ProgressBar_SetPos (hProgress3, 25)
    ProgressBar_SetBarColor (hProgress3, rgb(0,128,0))
    ProgressBar_SetBkColor (hProgress3, rgb(128,0,0))

    DIALOG SHOW modeless hDlg


    while isWindow(hDlg)
    Msg = GetMessage(hDlg, wParam, lParam)

    select case Msg
    case %WM_INITDIALOG


    CASE %WM_TIMER
    GlobalMemoryStatus (lpBuffer)
    ProgressBar_SetPos (hProgress1, lpBuffer.dwAvailPhys)
    ProgressBar_SetPos (hProgress2, lpBuffer.dwAvailVirtual)
    ProgressBar_SetPos (hProgress3, 100-lpBuffer.dwMemoryLoad)

    control set text hDlg, 1000, "Free physical memory ( "+format$(lpBuffer.dwAvailPhys/1024/1024, "0")+" of "+format$(lpBuffer.dwTotalPhys/1024/1024, "0")+" MB )"
    control set text hDlg, 2000, "Free virtual memory ( "+format$(lpBuffer.dwAvailVirtual/1024/1024, "0")+" of "+format$(lpBuffer.dwTotalVirtual/1024/1024, "0")+" MB )"
    control set text hDlg, 3000, "Total free load ( "+format$(100-lpBuffer.dwMemoryLoad, "0")+" % )"

    CASE %WM_SYSCOMMAND

    SELECT CASE wParam

    CASE %SC_CLOSE
    EXIT WHILE

    END SELECT

    END SELECT

    wend

    KillTimer hDlg, %ID_TIMER
    DIALOG END hDlg

    FUNCTION ProgressBar_SetRange32 (BYVAL hProgress AS DWORD, BYVAL iLowLim AS LONG, BYVAL iHighLim AS LONG) AS DWORD
    FUNCTION = SendMessage (hProgress, %PBM_SETRANGE32, iLowLim, iHighLim)
    END FUNCTION

    FUNCTION ProgressBar_SetPos (BYVAL hProgress AS DWORD, BYVAL nNewPos AS LONG) AS LONG
    FUNCTION = SendMessage (hProgress, %PBM_SETPOS, nNewPos, 0)
    END FUNCTION

    FUNCTION ProgressBar_SetBarColor (BYVAL hProgress AS DWORD, BYVAL clrBar AS LONG) AS LONG
    FUNCTION = SendMessage (hProgress, %PBM_SETBARCOLOR, 0, clrBar)
    END FUNCTION


    FUNCTION ProgressBar_SetBkColor (BYVAL hProgress AS DWORD, BYVAL clrBk AS LONG) AS LONG
    FUNCTION = SendMessage (hProgress, %PBM_SETBKCOLOR, 0, clrBk)
    END FUNCTION [/code]

    Bye,
    Petr
    Learn 3D graphics with ThinBASIC, learn TBGL!
    Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB

  5. #5
    thinBasic author ErosOlmi's Avatar
    Join Date
    Sep 2004
    Location
    Milan - Italy
    Age
    57
    Posts
    8,777
    Rep Power
    10

    Re: Memory information

    Petr,

    I just discover how good is this example !!!!!
    Also, CPU load during script execution is close to zero.

    Thanks a lot.

    Request: can I add to official distribution?
    Attached Images Attached Images
    www.thinbasic.com | www.thinbasic.com/community/ | help.thinbasic.com
    Windows 10 Pro for Workstations 64bit - 32 GB - Intel(R) Xeon(R) W-10855M CPU @ 2.80GHz - NVIDIA Quadro RTX 3000

  6. #6
    Super Moderator Petr Schreiber's Avatar
    Join Date
    Aug 2005
    Location
    Brno - Czech Republic
    Posts
    7,128
    Rep Power
    732

    Re: Memory information

    Hi Eros,

    I'm glad you like it
    The minimal CPU load is possible due to the timer.

    If you like, please add it to the distribution


    Thanks,
    Petr
    Learn 3D graphics with ThinBASIC, learn TBGL!
    Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB

  7. #7
    Hey everyone,

    First time user of ThinBasic here and really enjoying it. I can really tell what a passion project this is for the developers!

    So, onto my first question. I loaded the Memory.tbasic sample code and it is reporting incorrect information (showing 4GB of RAM when 16GB is actually installed), which is called out in Microsoft's own documentation (https://docs.microsoft.com/en-us/win...almemorystatus) and so they recommend using the GlobalMemoryStatusEx (https://docs.microsoft.com/en-us/win...memorystatusex) function instead. Where I am stuck is that the type this function expects has different parameters and with different types, particularly DWORDLONG. What is the equivalent of this in ThinBasic? The updated structure must look like this:

    typedef struct _MEMORYSTATUSEX {
      DWORD     dwLength;
      DWORD     dwMemoryLoad;
      DWORDLONG ullTotalPhys;
      DWORDLONG ullAvailPhys;
      DWORDLONG ullTotalPageFile;
      DWORDLONG ullAvailPageFile;
      DWORDLONG ullTotalVirtual;
      DWORDLONG ullAvailVirtual;
      DWORDLONG ullAvailExtendedVirtual;
    } MEMORYSTATUSEX, *LPMEMORYSTATUSEX;
    
    Source: https://docs.microsoft.com/en-us/win...memorystatusex

    Thanks!

  8. #8
    thinBasic author ErosOlmi's Avatar
    Join Date
    Sep 2004
    Location
    Milan - Italy
    Age
    57
    Posts
    8,777
    Rep Power
    10
    Ciao,

    equivalent of DWORDLONG is QUAD in thinBasic. I will add DWORDLONG alias in next thinBasic release.

    Here an example of GlobalMemoryStatusEx usage.

      uses "console"
      
      TYPE MEMORYSTATUSEX
          dwLength         AS DWORD
          dwMemoryLoad     AS DWORD
          ullTotalPhys     AS QUAD
          ullAvailPhys     AS QUAD
          ullTotalPageFile AS QUAD
          ullAvailPageFile AS QUAD
          ullTotalVirtual  AS QUAD
          ullAvailVirtual  AS QUAD
          ullAvailExtendedVirtual AS QUAD
      END TYPE
    
    
      DECLARE function GlobalMemoryStatusEx LIB "KERNEL32.DLL" ALIAS "GlobalMemoryStatusEx" (lpBuffer AS MEMORYSTATUSEX) as long
    
    
      global memStatusEx AS MEMORYSTATUSEX
    
    
      memStatusEx.dwLength = SIZEOF(MEMORYSTATUSEX)
      IF ISFALSE(GlobalMemoryStatusEx( memStatusEx )) THEN
        print "Error"
      else
        printl "Memory:"
        printl "Total     bytes", memStatusEx.ullTotalPhys
        printl "Available bytes", memStatusEx.ullAvailPhys
      end If
      printl "Press a key to end"
      WaitKey
    
    www.thinbasic.com | www.thinbasic.com/community/ | help.thinbasic.com
    Windows 10 Pro for Workstations 64bit - 32 GB - Intel(R) Xeon(R) W-10855M CPU @ 2.80GHz - NVIDIA Quadro RTX 3000

  9. #9
    thinBasic MVPs
    Join Date
    Oct 2012
    Location
    Germany
    Age
    54
    Posts
    1,528
    Rep Power
    170
    ull = unsigned long long, i would use the quad-type since it provides the 64 bits.
    Alternative you can use 2 dwords and calculate Number X = dw1 + dw2 * 4294967295

    Its a matter of interpretation. No need to create an udt for original BYREF <name as type> passed parameters you can allocate a buffer that provides the required size or more and change the declaration to ByVal pBuffer As DWORD
    
    ' the functions declaration. Use ALIAS in thinBasic always and name it as you like
    ' since its of the WinAPI i am used to prefix it "Win_" & "<whatItDoes>"
    Declare Function Win_ReadMemoryStatus Lib "kernel32.dll" alias "GlobalMemoryStatusEx" (byval pBuffer As Dword) As Long
    ' that one to check installed RAM:
    Declare Function Win_GetRam Lib "Kernel32.dll" Alias "GetPhysicallyInstalledSystemMemory" (byval pUInt64_Ram_kB as dword) as Boolean
    
    
    
    
    ' the original declaration does not say ByVal nor ByRef for the lpMemoryStatusEx
    ' but if none it means ByRef in the WinAPI while thinBasic defaults to ByVal if
    ' not given.
    ' You can use ByRef but then you must create a variable-type
    ' that matches the original type at least in size. 
    ' How you read it is up to you
                    
    ' instead of passing a matching type ByRef we can use a Dword that holds a pointer
    ' it must point to any buffer where the api-function will find the required space
    ' you can use a dynamic string, fixed length string or just any allocated memory, 
    ' even a variable if its large enough (see Win_GetRam) using a quad (2*32 Bit) as
    ' buffer. 
    '
    '  DWORD     dwLength;                
    '  DWORD     dwMemoryLoad;          
    '  DWORDLONG ullTotalPhys;           
    '  DWORDLONG ullAvailPhys;             
    '  DWORDLONG ullTotalPageFile;        
    '  DWORDLONG ullAvailPageFile;       
    '  DWORDLONG ullTotalVirtual;        
    '  DWORDLONG ullAvailVirtual;         
    '  DWORDLONG ullAvailExtendedVirtual"
    '
    '' now it remains the names only delimited by semicolon ";"
    ' parse the names to an array of string
     string SubElement$() 
     parse "dwLength;dwMemoryLoad;ullTotalPhys;ullAvailPhys;ullTotalPageFile;ullAvailPageFile;ullTotalVirtual;ullAvailVirtual;ullAvailExtendedVirtual",
                    SubElement$, ";"
                    
    ' the MEMORYSTATUSEX structure contains 9 elements of 2 types
    ' 2  32Bit-dwords and
    ' 7  64Bit-dwords - altogether 64 bytes
    ' so create a buffer of 64 bytes 
    ' pStatus contains where the buffer starts
    Dword pStatus = heap_Alloc(64)
    ' dwLength is a subelement that must contain the buffer size
    ' as the information on microsoft says -look up- its the
    ' very first four bytes of our buffer at pStatus 
    ' lets have virtually an array of Dword upon the buffer that
    ' covers the allocated 64 bytes completely
    dim vDword(heap_Size(pStatus)/SizeOf(Dword)) As Dword at pStatus
    ' now Heap_Size(pStatus) is 64 bytes
    ' sizeof(Dword) is 4
    ' 64/4 = we have created an array of 16 DWord-elements At pStatus 
    '    or
    ' we assigned the names vDword(1) to vDword(16) to that memory area
    ' which starts at the position contained in pStatus that we can access
    ' using HEAP_-functions as well 
    ' dwLength was the first? and must contain the buffers size- ok:
    
    
    vDword(1) = Heap_Size(pStatus) 
    ' thats the same as 
    Poke(Dword, pStatus, 64) 
    
    
    ' now call, provide the VALue in pStatus ByVal- the address of our buffer
    Long lResult = Win_ReadMemoryStatus(pStatus)
    ' instead of passing a variable byref 
    
    
    String sResult =  "Memory status resulted 0x" & hex$(lResult,8) & CRLF
           sResult &= "Element " & repeat$(50,".") & " Value" & CRLF
           
    ' now we prepared the names in an array named Subelement$()
    long l
    Long Index = 1 ' arrays in thinBasic are 1-based
                   ' this will keep track of virtual vDword
                   ' but as the vartype is 64Bit unsigned LongLong
                   ' (while LongLong were signed and equals Type Quad)
                   ' lets try both: and have a quad-array upon the DWORDLONG
    Dim vQuad(7) as Quad at pStatus + 8
    '     vQuad(1) will be after vDword(1) and vDword(2) each 4 bytes, so + 8
    '    l will be 3 already (3rd subelement) upon vQuad(1) means to subtract 2 of l
    ' if memory is interpreted as Quad. if there were negative numbers we could 
    ' use Type NUMBER (10 bytes) and multiply the HI vDword of each pair with     
    ' the highest value in range of dword and add the LO of the dword-pair
    Dword dwRangeHigh = 0xFFFFFFFF 
    Number BigNumber
                                
    for l = 1 to 9
        sResult &= subelement$(l) & "                 :        "
        if startsWith(subelement$(l), "dw") Then
            ' current Element is a Dword
            sResult &= tstr$(vDword(Index)) & crlf
            ' 1 more vDword was used:
            Index += 1
        Else
            ' starts with "ull"
            ' first As QUAD
            sResult &= tstr$(vQuad(l-2)) & Repeat$(2, $Tab)
            ' then As NUMBER
            BigNumber = vDword(Index) + dwRangeHigh * vDword(Index+1)
            sResult &= tstr$(BigNumber) & CRLF
            Index += 2 ' used 2 of vDword to display this
        EndIf
    Next
    ' append 1 more line since the last one ends with a newline
    
    
    quad ram_in_kB 
    Boolean bRes = Win_GetRam(varptr(ram_in_kB))
    sResult &= "Ram in MB = " & str$(ram_in_kb\1024)
    
    
    '##################################
    '### finally present the result ###
    '##################################
    
    
    msgBox sResult, %MB_ICONINFORMATION | %MB_OK, "Memory information"
    
    Last edited by ReneMiner; 08-11-2020 at 23:53.
    I think there are missing some Forum-sections as beta-testing and support

  10. #10

    Cool

    Eros and Rene, that is exactly the information I was looking for. Thank you very much for the help!

Page 1 of 2 12 LastLast

Similar Threads

  1. SDK no information
    By Michael Clease in forum Help Material
    Replies: 2
    Last Post: 14-11-2010, 23:22
  2. DLL information
    By sandyrepope in forum General
    Replies: 9
    Last Post: 30-04-2008, 02:59

Members who have read this thread: 1

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •