Yes I already have narrowed this down to a small test allocation. This
application allocates memory until it gets an out-of-memory exception.
When the exception occurs it will release what it just allocated.
Subsequent calls to GlobalMemoryStatus do not show the available system
memory recovering. Look below for the application.
Thanks
Rodger Higgins
using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;
namespace AllocTest
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class MainForm : System.Windows.Forms.Form
{
private System.Windows.Forms.Button HOGTest;
private System.Windows.Forms.ListView Results;
private System.Windows.Forms.ColumnHeader Metric;
private System.Windows.Forms.ColumnHeader Value;
private System.Windows.Forms.Button UpdateInfoButton;
private System.Windows.Forms.Button ExitApplication;
public MainForm()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
UpdateInfo() ;
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.Windows.Forms.ListViewItem listViewItem1 = new
System.Windows.Forms.ListViewItem();
System.Windows.Forms.ListViewItem.ListViewSubItem listViewSubItem1 =
new System.Windows.Forms.ListViewItem.ListViewSubItem();
System.Windows.Forms.ListViewItem listViewItem2 = new
System.Windows.Forms.ListViewItem();
System.Windows.Forms.ListViewItem.ListViewSubItem listViewSubItem2 =
new System.Windows.Forms.ListViewItem.ListViewSubItem();
System.Windows.Forms.ListViewItem listViewItem3 = new
System.Windows.Forms.ListViewItem();
System.Windows.Forms.ListViewItem.ListViewSubItem listViewSubItem3 =
new System.Windows.Forms.ListViewItem.ListViewSubItem();
System.Windows.Forms.ListViewItem listViewItem4 = new
System.Windows.Forms.ListViewItem();
System.Windows.Forms.ListViewItem.ListViewSubItem listViewSubItem4 =
new System.Windows.Forms.ListViewItem.ListViewSubItem();
System.Windows.Forms.ListViewItem listViewItem5 = new
System.Windows.Forms.ListViewItem();
System.Windows.Forms.ListViewItem.ListViewSubItem listViewSubItem5 =
new System.Windows.Forms.ListViewItem.ListViewSubItem();
System.Windows.Forms.ListViewItem listViewItem6 = new
System.Windows.Forms.ListViewItem();
System.Windows.Forms.ListViewItem.ListViewSubItem listViewSubItem6 =
new System.Windows.Forms.ListViewItem.ListViewSubItem();
System.Windows.Forms.ListViewItem listViewItem7 = new
System.Windows.Forms.ListViewItem();
System.Windows.Forms.ListViewItem.ListViewSubItem listViewSubItem7 =
new System.Windows.Forms.ListViewItem.ListViewSubItem();
System.Windows.Forms.ListViewItem listViewItem8 = new
System.Windows.Forms.ListViewItem();
System.Windows.Forms.ListViewItem.ListViewSubItem listViewSubItem8 =
new System.Windows.Forms.ListViewItem.ListViewSubItem();
this.ExitApplication = new System.Windows.Forms.Button();
this.HOGTest = new System.Windows.Forms.Button();
this.Results = new System.Windows.Forms.ListView();
this.Metric = new System.Windows.Forms.ColumnHeader();
this.Value = new System.Windows.Forms.ColumnHeader();
this.UpdateInfoButton = new System.Windows.Forms.Button();
//
// ExitApplication
//
this.ExitApplication.Location = new System.Drawing.Point(248, 0);
this.ExitApplication.Size = new System.Drawing.Size(72, 24);
this.ExitApplication.Text = "E&xit";
this.ExitApplication.Click += new
System.EventHandler(this.ExitApplication_Click);
//
// HOGTest
//
this.HOGTest.Size = new System.Drawing.Size(120, 24);
this.HOGTest.Text = "Run HOG Test";
this.HOGTest.Click += new System.EventHandler(this.HOGTest_Click);
//
// Results
//
this.Results.Columns.Add(this.Metric);
this.Results.Columns.Add(this.Value);
listViewSubItem1.Text = "Not Run";
listViewItem1.SubItems.Add(listViewSubItem1);
listViewItem1.Text = "GC.GetTotalMemory";
listViewSubItem2.Text = "Not Run";
listViewItem2.SubItems.Add(listViewSubItem2);
listViewItem2.Text = "GMS.dwMemoryLoad";
listViewSubItem3.Text = "Not Run";
listViewItem3.SubItems.Add(listViewSubItem3);
listViewItem3.Text = "GMS.dwTotalPhys";
listViewSubItem4.Text = "Not Run";
listViewItem4.SubItems.Add(listViewSubItem4);
listViewItem4.Text = "GMS.dwAvailPhys";
listViewSubItem5.Text = "Not Run";
listViewItem5.SubItems.Add(listViewSubItem5);
listViewItem5.Text = "GMS.dwTotalPage";
listViewSubItem6.Text = "Not Run";
listViewItem6.SubItems.Add(listViewSubItem6);
listViewItem6.Text = "GMS.dwAvailPage";
listViewSubItem7.Text = "Not Run";
listViewItem7.SubItems.Add(listViewSubItem7);
listViewItem7.Text = "GMS.dwTotalVirtual";
listViewSubItem8.Text = "Not Run";
listViewItem8.SubItems.Add(listViewSubItem8);
listViewItem8.Text = "GMS.dwAvailVirtual";
this.Results.Items.Add(listViewItem1);
this.Results.Items.Add(listViewItem2);
this.Results.Items.Add(listViewItem3);
this.Results.Items.Add(listViewItem4);
this.Results.Items.Add(listViewItem5);
this.Results.Items.Add(listViewItem6);
this.Results.Items.Add(listViewItem7);
this.Results.Items.Add(listViewItem8);
this.Results.Location = new System.Drawing.Point(0, 24);
this.Results.Size = new System.Drawing.Size(320, 216);
this.Results.View = System.Windows.Forms.View.Details;
//
// Metric
//
this.Metric.Text = "Metric";
this.Metric.Width = 200;
//
// Value
//
this.Value.Text = "Value";
this.Value.Width = 100;
//
// UpdateInfoButton
//
this.UpdateInfoButton.Location = new System.Drawing.Point(120, 0);
this.UpdateInfoButton.Size = new System.Drawing.Size(72, 24);
this.UpdateInfoButton.Text = "Update";
this.UpdateInfoButton.Click += new
System.EventHandler(this.UpdateInfoButton_Click);
//
// MainForm
//
this.ClientSize = new System.Drawing.Size(320, 240);
this.Controls.Add(this.UpdateInfoButton);
this.Controls.Add(this.Results);
this.Controls.Add(this.HOGTest);
this.Controls.Add(this.ExitApplication);
this.Text = "Allocate Test";
this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
this.Resize += new System.EventHandler(this.MainForm_OnResize);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
Application.Run(new MainForm());
}
private void ExitApplication_Click(object sender, System.EventArgs e)
{
this.Close() ;
}
private void HOGTest_Click(object sender, System.EventArgs e)
{
Chunks c = new Chunks() ;
for ( int i = 0 ; i < 1000 ; i++ )
{
try
{
Chunk ch = new Chunk() ;
c.Add( ch ) ;
}
catch ( OutOfMemoryException )
{
c.Clear() ;
UpdateInfo() ;
//MessageBox.Show("Out Of Memory","Error") ;
break ;
}
UpdateInfo() ;
}
System.GC.Collect() ;
System.GC.WaitForPendingFinalizers() ;
UpdateInfo() ;
}
private void UpdateInfo()
{
Results.Items[0].SubItems[1].Text = System.GC.GetTotalMemory( true
).ToString("N") ;
SystemMemoryStatus ms = new SystemMemoryStatus() ;
ms.Update() ;
Results.Items[1].SubItems[1].Text = ms.m_nMemoryLoad.ToString( "N" )
;
Results.Items[2].SubItems[1].Text = ms.m_nTotalPhys.ToString( "N" )
;
Results.Items[3].SubItems[1].Text = ms.m_nAvailPhys.ToString( "N" )
;
Results.Items[4].SubItems[1].Text = ms.m_nTotalPageFile.ToString(
"N" ) ;
Results.Items[5].SubItems[1].Text = ms.m_nAvailPageFile.ToString(
"N" ) ;
Results.Items[6].SubItems[1].Text = ms.m_nTotalVirtual.ToString( "N"
) ;
Results.Items[7].SubItems[1].Text = ms.m_nAvailVirtual.ToString( "N"
) ;
this.Update() ;
}
private void MainForm_OnResize(object sender, System.EventArgs e)
{
HOGTest.Location = new System.Drawing.Point( 0, 0 ) ;
UpdateInfoButton.Location = new System.Drawing.Point(
HOGTest.Size.Width, 0 ) ;
ExitApplication.Location = new System.Drawing.Point(
this.Size.Width - ExitApplication.Size.Width, 0 ) ;
Results.Location = new System.Drawing.Point(
0,
HOGTest.Size.Height ) ;
Results.Size = new System.Drawing.Size(
this.Width,
this.Height - HOGTest.Size.Height ) ;
Results.Columns[0].Width = Results.Size.Width -
Results.Columns[1].Width - 2 ;
}
private void UpdateInfoButton_Click(object sender, System.EventArgs
e)
{
UpdateInfo() ;
}
}
public class Chunk
{
private byte [] chunk ;
private const int ChunkSize = 64 * 1024 ;
public Chunk()
{
chunk = new byte[ChunkSize] ;
}
~Chunk()
{
}
}
public class Chunks : ArrayList
{
public Chunks()
{
}
public void Add(Chunk chunk)
{
base.Add(chunk);
}
public new Chunk this[int Index]
{
get
{
return (Chunk)base[Index];
}
set
{
base[Index] = value;
}
}
}
public class SystemMemoryStatus
{
public int m_nMemoryLoad ;
public int m_nTotalPhys ;
public int m_nAvailPhys ;
public int m_nTotalPageFile ;
public int m_nAvailPageFile ;
public int m_nTotalVirtual ;
public int m_nAvailVirtual ;
private struct MEMORYSTATUS
{
public int dwLength;
public int dwMemoryLoad;
public int dwTotalPhys;
public int dwAvailPhys;
public int dwTotalPageFile;
public int dwAvailPageFile;
public int dwTotalVirtual;
public int dwAvailVirtual;
} ;
[DllImport("coredll.dll", SetLastError=true)]
static extern void GlobalMemoryStatus (ref MEMORYSTATUS lpBuffer) ;
public SystemMemoryStatus()
{
}
public void Update()
{
MEMORYSTATUS ms = new MEMORYSTATUS() ;
ms.dwLength = System.Runtime.InteropServices.Marshal.SizeOf( ms ) ;
GlobalMemoryStatus( ref ms ) ;
m_nMemoryLoad = ms.dwMemoryLoad ;
m_nTotalPhys = ms.dwTotalPhys ;
m_nAvailPhys = ms.dwAvailPhys ;
m_nTotalPageFile = ms.dwTotalPageFile ;
m_nAvailPageFile = ms.dwAvailPageFile ;
m_nTotalVirtual = ms.dwTotalVirtual ;
m_nAvailVirtual = ms.dwAvailVirtual ;
}
}
}