Thread: virtual memory program

  1. #1
    Registered User
    Join Date
    Nov 2003
    Posts
    27

    virtual memory program

    Code:
    // VMStatsDlg.cpp : implementation file
    //
    
    #include "stdafx.h"
    #include "VMStats.h"
    #include "VMStatsDlg.h"
    
    #include <winbase.h>	// For GlobalMemoryStatus and MEMORYSTATUS
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif
    
    
    void AFXAPI DDX_Text_Custom(CDataExchange* pDX, int nIDC, unsigned long& value);
    void AFX_CDECL My_DDX_TextWithFormat(CDataExchange* pDX, int nIDC,
    	LPCTSTR lpszFormat, UINT nIDPrompt, ...);
    
    /////////////////////////////////////////////////////////////////////////////
    // CAboutDlg dialog used for App About
    
    class CAboutDlg : public CDialog
    {
    public:
    	CAboutDlg();
    
    // Dialog Data
    	//{{AFX_DATA(CAboutDlg)
    	enum { IDD = IDD_ABOUTBOX };
    	//}}AFX_DATA
    
    	// ClassWizard generated virtual function overrides
    	//{{AFX_VIRTUAL(CAboutDlg)
    	protected:
    	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
    	//}}AFX_VIRTUAL
    
    // Implementation
    protected:
    	//{{AFX_MSG(CAboutDlg)
    	//}}AFX_MSG
    	DECLARE_MESSAGE_MAP()
    };
    
    CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
    {
    	//{{AFX_DATA_INIT(CAboutDlg)
    	//}}AFX_DATA_INIT
    }
    
    void CAboutDlg::DoDataExchange(CDataExchange* pDX)
    {
    	CDialog::DoDataExchange(pDX);
    	//{{AFX_DATA_MAP(CAboutDlg)
    	//}}AFX_DATA_MAP
    }
    
    BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
    	//{{AFX_MSG_MAP(CAboutDlg)
    		// No message handlers
    	//}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    
    /////////////////////////////////////////////////////////////////////////////
    // CVMStatsDlg dialog
    
    CVMStatsDlg::CVMStatsDlg(CWnd* pParent /*=NULL*/)
    	: CDialog(CVMStatsDlg::IDD, pParent)
    {
    	//{{AFX_DATA_INIT(CVMStatsDlg)
    	m_AvPage = 0;
    	m_AvPhys = 0;
    	m_AvVirt = 0;
    	m_Percent = 0;
    	m_TotPage = 0;
    	m_TotPhys = 0;
    	m_TotVirt = 0;
    	//}}AFX_DATA_INIT
    	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
    	m_hIcon = AfxGetApp()->LoadIcon(IDI_CHIPICON);
    
        m_nReserved = m_nCommitted = m_nUsed = 0;
    }
    
    void CVMStatsDlg::DoDataExchange(CDataExchange* pDX)
    {
    	CDialog::DoDataExchange(pDX);
    /*
    	//{{AFX_DATA_MAP(CVMStatsDlg)
    	DDX_Text(pDX, IDC_AVPAGE, m_AvPage);
    	DDX_Text(pDX, IDC_AVPHYS, m_AvPhys);
    	DDX_Text(pDX, IDC_AVVIRT, m_AvVirt);
    	DDX_Text(pDX, IDC_PERCENT, m_Percent);
    	DDX_Text(pDX, IDC_TOTPAGE, m_TotPage);
    	DDX_Text(pDX, IDC_TOTPHYS, m_TotPhys);
    	DDX_Text(pDX, IDC_TOTVIRT, m_TotVirt);
    	//}}AFX_DATA_MAP
    */
    	DDX_Text_Custom(pDX, IDC_AVPAGE, m_AvPage);
    	DDX_Text_Custom(pDX, IDC_AVPHYS, m_AvPhys);
    	DDX_Text_Custom(pDX, IDC_AVVIRT, m_AvVirt);
    	DDX_Text_Custom(pDX, IDC_PERCENT, m_Percent);
    	DDX_Text_Custom(pDX, IDC_TOTPAGE, m_TotPage);
    	DDX_Text_Custom(pDX, IDC_TOTPHYS, m_TotPhys);
    	DDX_Text_Custom(pDX, IDC_TOTVIRT, m_TotVirt);
    }
    
    BEGIN_MESSAGE_MAP(CVMStatsDlg, CDialog)
    	//{{AFX_MSG_MAP(CVMStatsDlg)
    	ON_WM_SYSCOMMAND()
    	ON_WM_PAINT()
    	ON_WM_QUERYDRAGICON()
    	ON_WM_CREATE()
    	ON_WM_DESTROY()
    	ON_WM_TIMER()
    	ON_BN_CLICKED(IDC_ABOUT, OnAbout)
    	ON_BN_CLICKED(IDC_RESERVE, OnReserve)
    	ON_BN_CLICKED(IDC_USE, OnUse)
    	ON_BN_CLICKED(IDC_RADIODEC, OnRadiodec)
    	ON_BN_CLICKED(IDC_RADIOHEX, OnRadiohex)
    	ON_BN_CLICKED(IDC_COMMIT, OnCommit)
    	//}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    
    /////////////////////////////////////////////////////////////////////////////
    // CVMStatsDlg message handlers
    
    BOOL CVMStatsDlg::OnInitDialog()
    {
    	CDialog::OnInitDialog();
    
    	// Add "About..." menu item to system menu.
    
    	// IDM_ABOUTBOX must be in the system command range.
    	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    	ASSERT(IDM_ABOUTBOX < 0xF000);
    
    	CMenu* pSysMenu = GetSystemMenu(FALSE);
    	if (pSysMenu != NULL)
    	{
    		CString strAboutMenu;
    		strAboutMenu.LoadString(IDS_ABOUTBOX);
    		if (!strAboutMenu.IsEmpty())
    		{
    			pSysMenu->AppendMenu(MF_SEPARATOR);
    			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
    		}
    	}
    
    	// Set the icon for this dialog.  The framework does this automatically
    	//  when the application's main window is not a dialog
    	SetIcon(m_hIcon, TRUE);			// Set big icon
    	SetIcon(m_hIcon, FALSE);		// Set small icon
    	
    	// TODO: Add extra initialization here
     
        m_DisplayFmtHex = TRUE;  
       TCHAR szBuf[60];
       _stprintf(szBuf, __TEXT("System page size %dKB"), m_PageSize/1024);
       ::SetDlgItemText(m_hWnd, IDC_PAGESIZE, szBuf);
    //   SetDlgItemText(IDC_PAGESIZE, szBuf);
       _stprintf(szBuf, __TEXT("Virtual memory allocation granularity %dKB"), m_Granularity/1024);
       ::SetDlgItemText(m_hWnd, IDC_GRANULARITY, szBuf);  
    //  SetDlgItemText(IDC_GRANULARITY, szBuf);
    
       CheckRadioButton(IDC_RADIODEC, IDC_RADIOHEX, IDC_RADIOHEX);
    
    	return TRUE;  // return TRUE  unless you set the focus to a control
    }
    
    void CVMStatsDlg::OnSysCommand(UINT nID, LPARAM lParam)
    {
    	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    	{
    		CAboutDlg dlgAbout;
    		dlgAbout.DoModal();
    	}
    	else
    	{
    		CDialog::OnSysCommand(nID, lParam);
    	}
    }
    
    // If you add a minimize button to your dialog, you will need the code below
    //  to draw the icon.  For MFC applications using the document/view model,
    //  this is automatically done for you by the framework.
    
    void CVMStatsDlg::OnPaint() 
    {
    	if (IsIconic())
    	{
    		CPaintDC dc(this); // device context for painting
    
    		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
    
    		// Center icon in client rectangle
    		int cxIcon = GetSystemMetrics(SM_CXICON);
    		int cyIcon = GetSystemMetrics(SM_CYICON);
    		CRect rect;
    		GetClientRect(&rect);
    		int x = (rect.Width() - cxIcon + 1) / 2;
    		int y = (rect.Height() - cyIcon + 1) / 2;
    
    		// Draw the icon
    		dc.DrawIcon(x, y, m_hIcon);
    	}
    	else
    	{
    		CDialog::OnPaint();
    	}
    }
    
    // The system calls this to obtain the cursor to display while the user drags
    //  the minimized window.
    HCURSOR CVMStatsDlg::OnQueryDragIcon()
    {
    	return (HCURSOR) m_hIcon;
    }
    
    int CVMStatsDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) 
    {
    	if (CDialog::OnCreate(lpCreateStruct) == -1)
    		return -1;
    	
    	// TODO: Add your specialized creation code here
    
    	SYSTEM_INFO SystemInfo;
    
    	GetSystemInfo(&SystemInfo);
    	m_PageSize = SystemInfo.dwPageSize;
    	m_Granularity = SystemInfo.dwAllocationGranularity;
    
    	m_MemoryStatus.dwLength = sizeof(m_MemoryStatus);
    	GlobalMemoryStatus(&m_MemoryStatus);
    	m_AvPage = m_MemoryStatus.dwAvailPageFile;
    	m_AvPhys = m_MemoryStatus.dwAvailPhys;
    	m_AvVirt = m_MemoryStatus.dwAvailVirtual;
    	m_Percent = m_MemoryStatus.dwMemoryLoad;
    	m_TotPage = m_MemoryStatus.dwTotalPageFile;
    	m_TotPhys = m_MemoryStatus.dwTotalPhys;
    	m_TotVirt = m_MemoryStatus.dwTotalVirtual;
    
    	if((m_TimerID = SetTimer(1, 100, NULL)) == 0){
    		MessageBox("No system timer available");
    	}
    	return 0;
    }
    
    void CVMStatsDlg::OnDestroy() 
    {
    	CDialog::OnDestroy();
    	
    	// TODO: Add your message handler code here
    	if(m_TimerID != 0)
    		KillTimer(m_TimerID);	
    }
    
    void CVMStatsDlg::OnTimer(UINT nIDEvent) 
    {
    	// TODO: Add your message handler code here and/or call default
    	BOOL changed = FALSE;
    	m_MemoryStatus.dwLength = sizeof(m_MemoryStatus);
    	GlobalMemoryStatus(&m_MemoryStatus);
    	if(m_AvPage != m_MemoryStatus.dwAvailPageFile){
    		m_AvPage = m_MemoryStatus.dwAvailPageFile;
    		changed = TRUE;
    	}
    	if(m_AvPhys != m_MemoryStatus.dwAvailPhys){
    		m_AvPhys = m_MemoryStatus.dwAvailPhys;
    		changed = TRUE;
    	}
    	if(m_AvVirt != m_MemoryStatus.dwAvailVirtual){
    		m_AvVirt = m_MemoryStatus.dwAvailVirtual;
    		changed = TRUE;
    	}
    	if(m_Percent != m_MemoryStatus.dwMemoryLoad){
    		m_Percent = m_MemoryStatus.dwMemoryLoad;
    		changed = TRUE;
    	}
    	if(m_TotPage != m_MemoryStatus.dwTotalPageFile){
    		m_TotPage = m_MemoryStatus.dwTotalPageFile;
    		changed = TRUE;
    	}
    	if(m_TotPhys != m_MemoryStatus.dwTotalPhys){
    		m_TotPhys = m_MemoryStatus.dwTotalPhys;
    		changed = TRUE;
    	}
    	if(m_TotVirt != m_MemoryStatus.dwTotalVirtual){
    		m_TotVirt = m_MemoryStatus.dwTotalVirtual;
    		changed = TRUE;
    	}
    	if(changed)UpdateData(FALSE);
    	CDialog::OnTimer(nIDEvent);
    }
    
    void CVMStatsDlg::OnAbout() 
    {
    	// TODO: Add your control notification handler code here
    	CAboutDlg AboutDlg;
    	AboutDlg.DoModal();	
    }
    
    void CVMStatsDlg::OnReserve() 
    {
    	// TODO: Add your control notification handler code here
    	m_DataBlocks[m_nReserved++] = (char *)VirtualAlloc(NULL, 65536, MEM_RESERVE, PAGE_READWRITE);
    }
    
    void CVMStatsDlg::OnUse() 
    {
    	// TODO: Add your control notification handler code here
        if(m_nCommitted > m_nUsed){
            char *p = m_DataBlocks[m_nUsed++];
            for(int i = 0; i < 65536; i++){
                for(int j = 0; j < 256; j++)
                    *p = j;
                p++;
            }
        }
    }
    
    void CVMStatsDlg::OnRadiodec() 
    {
    	// TODO: Add your control notification handler code here
    	m_DisplayFmtHex = FALSE;
    	
    }
    
    void CVMStatsDlg::OnRadiohex() 
    {
    	// TODO: Add your control notification handler code here
    	m_DisplayFmtHex = TRUE;
    }
    
    
    void AFXAPI DDX_Text_Custom(CDataExchange* pDX, int nIDC, unsigned long& value)
    {
    	if (pDX->m_bSaveAndValidate)
    		My_DDX_TextWithFormat(pDX, nIDC, _T("%X"), AFX_IDP_PARSE_INT, &value);
    	else
            if(((CVMStatsDlg *)AfxGetMainWnd())->m_DisplayFmtHex)
    		    My_DDX_TextWithFormat(pDX, nIDC, _T("%X"), AFX_IDP_PARSE_INT, value);
            else
    		    My_DDX_TextWithFormat(pDX, nIDC, _T("%d"), AFX_IDP_PARSE_INT, value);
    }
    
    
    void AFX_CDECL My_DDX_TextWithFormat(CDataExchange* pDX, int nIDC,
    	LPCTSTR lpszFormat, UINT nIDPrompt, ...)
    	// only supports windows output formats - no floating point
    {
    	va_list pData;
    	va_start(pData, nIDPrompt);
    
    	HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);
    	TCHAR szT[32];
    	if (pDX->m_bSaveAndValidate)
    	{
    		/*
    		// the following works for %d, %u, %ld, %lu
    		::GetWindowText(hWndCtrl, szT, _countof(szT));
    		if (!_AfxSimpleScanf(szT, lpszFormat, pData))
    		{
    			AfxMessageBox(nIDPrompt);
    			pDX->Fail();        // throws exception
    		}
    		*/
    	}
    	else
    	{
    		wvsprintf(szT, lpszFormat, pData);
    			// does not support floating point numbers - see dlgfloat.cpp
    		SetWindowText(hWndCtrl, szT);
    	}
    
    	va_end(pData);
    }
    
    void CVMStatsDlg::OnCommit() 
    {
    	// TODO: Add your control notification handler code here
        if(m_nReserved > m_nCommitted)
    	    VirtualAlloc(m_DataBlocks[m_nCommitted++], 65536, MEM_COMMIT, PAGE_READWRITE);	
    }

    hi,

    can anyone help? I can't work out a few things relating to the above code:

    - What do the reserve,commit and use buttons do?

    - What is the difference between the page file and
    virtual memory?

    - How does this approach differ to simply using malloc
    and when would it be more appropriate?

    - What Win32 function is used in the
    timer handler to obtain system virtual memory
    information?



    thanks, any input would be great.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Moved to windows board, and smilies turned off for C++ code
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Nov 2003
    Posts
    27
    anyone got any ideas? thanks,

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Yeah, stop bumping your threads - read the rules
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    .
    Join Date
    Nov 2003
    Posts
    307
    - What is the difference between the page file and
    virtual memory?
    The pagefile holds process pages (512 byte pages) that are currently not being used and that the OS thinks the process does not need.

    For a process to have an amount of virtual memory,
    that is memory that it could use, but may or may not use -
    in Windows you call VirtualAlloc(). This sets up the process header memory information, and reserves (but does not actually use) pagefile space for that memory. This is why later versions of Windows suggest that you do not specify pagefile size.

    The original 'virtual machine' designs from the early 70's were machines in which each process, in theory, could have more memory allocated to it than existed on the physical machine.
    'Extra' memory that did not fit inot memory was removed from memory and parked in a pagefile. Inactive processes entire memory was swapped out to a swapfile to make more room in real memory for the currently active process.

    Therefore, virtual memory was what the process could theoretically use by combining all of memory plus the swap/page files. Things fell apart when processes really tried to push that.

  6. #6
    Registered User
    Join Date
    Nov 2003
    Posts
    27

    when to use virtual alloc

    thats great,

    when would it be a good idea to use virtual Alloc instead of malloc? could you give me some "real" examples?

  7. #7
    Registered User
    Join Date
    Jun 2003
    Posts
    245
    When you need more control over your memory allocate than what "malloc" provides. Check the MSDN.

  8. #8
    Registered User
    Join Date
    Nov 2003
    Posts
    27
    so,

    i press the use button and it writes something to a VM block. Exactly what is it writing? Just 1's? And, how much each time i press it? 64Kb or as much as i have commited?

  9. #9
    Registered User
    Join Date
    Nov 2003
    Posts
    27

    when to use Virtual Alloc

    Can you explain when it would be more appropriate to use
    virtual alloc rahter than malloc in laymans terms?

    I looked in the MSDN library, but it may as well be in Swahili.

    thanks for all your help.

  10. #10
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    VirtualAlloc should not be used as a general replacement for malloc. It allows you to reserve a section of memory in the virtual address space and is not optimised for quick and simple heap based memory allocation as malloc is.

    If you really feel you must use an API for memory allocation, then look towards HeapAlloc, but malloc often uses this (on many windows compilers) and so there will be little gain in calling it outright.

  11. #11
    Registered User
    Join Date
    Nov 2003
    Posts
    27

    hmm

    that still doesn't explain when it would be better to use virtual alloc. Is virtual alloc pointless?

  12. #12
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793

    Re: hmm

    Originally posted by funkylunch
    that still doesn't explain when it would be better to use virtual alloc. Is virtual alloc pointless?
    It wouldnt be better to use VirtualAlloc unless you needed to allocate a block of memory that you dont want to accomodate in the heap (such as a large block of memory that you dont want to burden your heap with)....or if you need to allocate a block at a specific point in your usermode address space

    I imagine that when you call LoadLibrary to load a dll at runtime, there might be a call to VirtualAlloc to reserve some memory for that image within your address space before the contents of the dll are loaded into memory......that might be the case - I havent sat there with a debugger to test it, but it gives you an idea as to it's uses. Look out for some of the earlier books by Jeff Prosise such as Advanced windows...that will give you a good look at this type of stuff

  13. #13
    Registered User
    Join Date
    Nov 2003
    Posts
    27

    Virtual Memory Allocation

    do you mean "when" instead of "unless"?

    why would i not want to burden my heap with something?

    why would i want to allocate a block at a specific point in my usermode address space?

    Why would Loadlibrary reserve some virtual memory for a dll at runtime instead of physical memory?

    would you classify virtual memory as an "overflow" or "emergency" area of memory??

  14. #14
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793

    Re: Virtual Memory Allocation

    Originally posted by funkylunch
    do you mean "when" instead of "unless"?
    "It wouldnt be better to use VirtualAlloc unless blah blah blah" == "Dont use VirtualAlloc unless blah blah blah"

    Originally posted by funkylunch
    why would i not want to burden my heap with something?
    Say you needed a static region of memory and you didnt want to risk overloading the heap which is used for the rest of your program

    Originally posted by funkylunch
    why would i want to allocate a block at a specific point in my usermode address space?
    I cant think of a specific example, but if you needed a block of memory on a page alignment for whatever reason this might help that

    Originally posted by funkylunch
    Why would Loadlibrary reserve some virtual memory for a dll at runtime instead of physical memory?
    You dont need to decide the balance of physical memory...that is for the OS to decide...if you needed to stipulate that memory should be unpaged (reside in physical memory at all time) then most likely you are designing a kernel mode driver and there are specific APIs & tools to help that situation

    Originally posted by funkylunch
    would you classify virtual memory as an "overflow" or "emergency" area of memory??
    Neither...it's a memory that is part of a theoretical address space that either isnt actually reserved/committed, resides in a paging file or resides in memory

    If you are genuinely interested in this stuff...look out for the book I suggested...it will give you a better idea than anything you can get on forums

  15. #15
    Registered User
    Join Date
    Nov 2003
    Posts
    27

    my other problem

    fordy,

    can u help me with my other problem: memory access time?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Mutex and Shared Memory Segment Questions.
    By MadDog in forum Linux Programming
    Replies: 14
    Last Post: 06-20-2010, 04:04 AM
  2. Program crashes and memory leaks
    By ulillillia in forum Tech Board
    Replies: 1
    Last Post: 05-15-2007, 10:54 PM
  3. Using extended memory to store program data
    By Robby in forum C Programming
    Replies: 1
    Last Post: 01-11-2005, 08:19 AM
  4. Program uses a lot of memory and doesnt exit properly
    By TJJ in forum Windows Programming
    Replies: 13
    Last Post: 04-28-2004, 03:13 AM
  5. my C++ program hangs during memory deallocation.
    By the-tzar in forum C++ Programming
    Replies: 6
    Last Post: 03-06-2004, 10:39 AM