How to free memory?

New to FreeBASIC? Post your questions here.
zcbenz
Posts: 48
Joined: Jan 30, 2008 3:00

How to free memory?

Postby zcbenz » Feb 01, 2008 2:43

In the example below ,every time the "mTray" menu popups, the memory it used would gain from 1664kb to 2192kb ,and then it would stay the 2192kb forever ,even I didn't right click on the tray icon any more.

How could I get the used 530kb memory back?

Code: Select all

#include once "windows.bi"
#include once "win\shellapi.bi"
#include once "win\tlhelp32.bi"

Declare Function WinMain ( Byval hInstance As HINSTANCE, Byval hPrevInstance As HINSTANCE,szCmdLine As String, Byval iCmdShow As Integer ) As Integer

Const WM_SHELLNOTIFY = WM_USER + 5
Const ID_EXIT =1, ID_NONE =2, ID_FREE=3

Dim Shared iTray As NOTIFYICONDATA
Dim Shared mTray As HANDLE
Dim Shared szAppName As String
Dim Shared TB_CREATED As Integer
Dim Shared MainMenu As HANDLE

End WinMain( GetModuleHandle( null ), null, Command$, SW_NORMAL )

Function WndProc ( Byval hWnd As HWND, Byval message As UINT, Byval wParam As WPARAM, _
                Byval lParam As LPARAM ) As LRESULT

  Static pt As Point
  Function = 0

  Select Case (message)
  Case WM_CREATE
          TB_CREATED = RegisterWindowMessage ("TaskbarCreated")
          Exit Function

  Case WM_DESTROY
          UnregisterClass (szAppName, GetModuleHandle( null ))
          Shell_NotifyIcon (NIM_DELETE, @iTray)
          PostQuitMessage( 0 )
          Exit Function

  Case WM_COMMAND
          Select Case LOWORD (wParam)
              Case ID_EXIT
                DestroyWindow (hWnd)
             Case ID_NONE
                '
             Case ID_FREE
                '
          End Select

  Case WM_CREATE
          TB_CREATED = RegisterWindowMessage ("TaskbarCreated")

  Case WM_SHELLNOTIFY
       If lParam = WM_RBUTTONDOWN Then
          mTray = CreateMenu ()
         MainMenu = CreateMenu ()
         InsertMenu (MainMenu, 0, MF_POPUP, mTray, "invisible menu")
         
         InsertMenu (mTray, 0, MF_SEPARATOR, -1, "")
         InsertMenu (mTray, 1, MF_STRING, ID_EXIT, "E&xit")

         GetCursorPos (@pt)
         SetForegroundWindow (hWnd)
         TrackPopupMenuEx (mTray, TPM_LEFTALIGN Or TPM_RIGHTBUTTON, pt.x, pt.y, hWnd, NULL)
         PostMessage (hWnd, WM_NULL, 0, 0)
         DestroyMenu (MainMenu)
             
       EndIf
         
  Case TB_CREATED
          Shell_NotifyIcon (NIM_ADD, @iTray)
  End Select

  Function = DefWindowProc( hWnd, message, wParam, lParam )
End Function

Function WinMain ( Byval hInstance As HINSTANCE, _
                Byval hPrevInstance As HINSTANCE, _
                szCmdLine As String, _
                Byval iCmdShow As Integer ) As Integer

        Dim wMsg As MSG
        Dim wcls As WNDCLASS
        Dim hWnd As HWND

        Function = 0

        szAppName = "Auto Servicer"

    hWnd=FindWindow(szAppName,NULL)
    If hWnd <> 0 Then
        SetForegroundWindow(hWnd)
        Exit Function
    End If

        With wcls
                .style = CS_HREDRAW Or CS_VREDRAW
                .lpfnWndProc = @WndProc
                .cbClsExtra = 0
                .cbWndExtra = 0
                .hInstance  = hInstance
                .hIcon = LoadIcon( NULL, IDI_APPLICATION )
                .hCursor = LoadCursor( NULL, IDC_ARROW )
                .hbrBackground = GetStockObject( WHITE_BRUSH )
                .lpszMenuName = NULL
                .lpszClassName = Strptr( szAppName )
        End With

        If( RegisterClass( @wcls ) = FALSE ) Then
                MessageBox( null, "This program requires Windows NT!", szAppName, MB_ICONERROR )
                Exit Function
        End If

        '' Create the window and _BUT DONT_ show it
        hWnd = CreateWindowEx( 0, szAppName, "", _
        0, _
        0, 0, 0, 0, _
                NULL, NULL, _
                hInstance, _
                NULL )
               
        'Create Tray
        iTray.cbSize = sizeof (NOTIFYICONDATA)
        iTray.hWnd = hWnd
        'iTray.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (CLOCKICON))
        iTray.uFlags = NIF_TIP Or NIF_ICON Or NIF_MESSAGE Or NIF_INFO Or NIF_STATE
        iTray.uCallbackMessage = WM_SHELLNOTIFY
        iTray.szTip= szAppName
        Shell_NotifyIcon (NIM_ADD, @iTray)

       
        While( GetMessage( @wMsg, NULL, 0, 0 ) <> FALSE )
                TranslateMessage( @wMsg )
                DispatchMessage( @wMsg )
        Wend
        Function = wMsg.wParam
End Function
D.J.Peters
Posts: 7858
Joined: May 28, 2005 3:28

Postby D.J.Peters » Feb 01, 2008 4:11

Do you mean the memory from hidden window?

Joshy
zcbenz
Posts: 48
Joined: Jan 30, 2008 3:00

Postby zcbenz » Feb 01, 2008 4:40

Maybe , I don't exactly know which part uses the memory.

The same thing has happened for many times.For example,after using SoundPlay function ,the memory my programme used would add about 890kb. Everytime I called a new API function, the memory usage would gain a great deal. What I want to do is to free the used memory after having used an API function.

Sorry for my bad English.
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Postby MichaelW » Feb 01, 2008 5:21

Why does your WndProc select case contain two instances of case WM_CREATE? And why are you creating the menu in the WM_SHELLNOTIFY handler instead of in the WM_CREATE handler? The WM_CREATE message is sent only once, where the WM_SHELLNOTIFY message is sent repeatedly.
zcbenz
Posts: 48
Joined: Jan 30, 2008 3:00

Postby zcbenz » Feb 01, 2008 5:48

I need to refresh some information of the menu when it shows, so I create the menu under WM_SHELLNOTIFY handler.And the two WM_CREATE was just my mistake.

Here is the original code :http://t6l3iw.bay.livefilestore.com/y1pGBF5ZCHMoXaWMDYQFQ6bWmreXoiF8vLcuTB5JdeZQ1xf_ryT1jQDTlYAuEavv86v0KAI9U3R0dNgBEvSgffksvKPv_fGOtBD/FB%20Projects.zip?download

As you see,the memory it used gained a lot when the menu shows or the Playsound works.

Thanks for your help.
voodooattack
Posts: 605
Joined: Feb 18, 2006 13:30
Location: Alexandria / Egypt
Contact:

Postby voodooattack » Feb 01, 2008 18:54

Here's something I've used for an old framework called FBServ, I basically noticed the same problem, and as FBServ was built to create light-weight NT Services using FB, so I wrote this function to solve the problem:

Code: Select all

    Function SrvFlushPhysicalMem() As Integer
       
        SetLastError(NO_ERROR)
       
        Dim hProc   as HANDLE
        Dim dwMin   as UInteger
        Dim dwMax   as UInteger
        Dim ret     as Integer
       
        'Flush the process memory into the page file..
       
        'Obtain a handle for the current process
        hProc = OpenProcess(PROCESS_SET_QUOTA OR PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId())
       
        If hProc = INVALID_HANDLE_VALUE Then
            'Couldn't open a handle to the current process..
            'Just abort..
            ret = FALSE
        Else
            'Get the current working set size..
            If GetProcessWorkingSetSize(hProc, @dwMin, @dwMax) = FALSE Then
                'Could not get the current values, assume defaults
                dwMin = 204800  'default (~ 400KB)
                dwMax = 1413120 'default (~ 2MB)
            End If
           
            'Flush the process' physical memory..
            If SetProcessWorkingSetSize(hProc, cuint(-1), cuint(-1)) = FALSE Then       
                ret = FALSE
            Else
                ret = TRUE
            End If
           
            'Restore old values..
            If SetProcessWorkingSetSize(hProc, dwMin, dwMax) = FALSE Then       
                ret = FALSE
            End If
           
            'Close the handle
            CloseHandle(hProc)
        End If
       
        SetLastError(NO_ERROR)
       
        Return ret
       
    End Function


What it does is simply flush most of the pages in your program's virtual memory everytime it's called, then they'll be pulled out from the pagefile through the memory manager once needed.. helps keeping your apps to a small memory footprint, in exchange for (somewhat) slower memory access :)

can be a life saver if you don't overuse it..

Return to “Beginners”

Who is online

Users browsing this forum: No registered users and 1 guest