I need to get the 'Commit size' (Windows Task Manager > Details) of a process in C#.
At first sight the Process class does not provide a relevant property.
Can somebody help me?
Edited
private static void ShowCommitSize(string processName)
{
Process process = Process.GetProcessesByName(processName).FirstOrDefault();
if (process != null)
{
var pagedMemMb = ConvertBytesToMegabytes(process.PagedMemorySize64);
Console.WriteLine(process.ProcessName + "\t" + process.Id + "\t" + Math.Round(pagedMemMb, 3) + " MB");
}
Console.ReadLine();
}
static double ConvertBytesToMegabytes(long bytes)
{
return (bytes / 1024f) / 1024f;
}
Output
There is a difference between my calculated Commit Size and the 'Commit Size' in Task Manager. Any ideas?
Solution
private static void ShowCommitSize(string processName)
{
var process = Process.GetProcessesByName(processName).FirstOrDefault();
if (process != null)
{
var memKb = ConvertBytesToKilobytes(process.PagedMemorySize64);
Console.WriteLine(process.ProcessName + "\t" + process.Id + "\t" + memKb.ToString("N") + " K");
}
Console.ReadLine();
}
static double ConvertBytesToKilobytes(long bytes)
{
return (bytes / 1024f);
}
This value is in the PagedMemorySize64 property. The documentation mentions that this the "Page File Size" process performance counter and over here it is documented that this is referred to as "Commit Size" in Task Manager on Vista/2008 (and I would assume newer OSes).
Related
I have two functions using a lock statement, where after some operations finished, I redirect the output in a .txt file. I have realised that their executions take a lot of time, resulting in blocking their operations and degrading the app's performance in general.
I was thinking that the high execution time could be due to the write operations into a file. What would be the most efficient way to reduce the execution time? Should I use another thread for the write operations, is it possible inside a lock without holding the lock?
A simplified version of my code is illustrated below:
StatsInformation statsInfo = new StatsInformation ();
List<int> lInt = new List<int>();
public void FunctionEnq(List<byte> lByte, int _int)
{
lock (OperationLock)
{
//Do some work here
lInt.Add(_int);
string result = "New Int " + _int + " size " + lInt.Count + " time " + DateTime.Now.ToString("hh:mm:ss.fff");
statsInfo.WriteStatsInFile(result);
}
}
public (List<byte> _outByte, int _time) FunctionDeq()
{
List<byte> _outByte = new List<byte> ();
int _time = -1;
lock (OperationLock)
{
//Do some work here
_outByte.Add(...);
int _int = lInt[0];
//do operations
_time = _int;
lInt.RemoveAt(0);
string result = "Get Int " + _int + " new size " + lInt.Count + " time " + DateTime.Now.ToString("hh:mm:ss.fff");
statsInfo.WriteStatsInFile(result);
}
return (_outByte, _time);
}
Hi I have a program that downloads + extracts the files in parallel (in threads).
it is a console app,and I want to show the Progress Bar for each operation in each thread.
for eg:
File 1 [==========35% ] 35mb of 100mb downloaded
File 2 [====20% ] 20mb of 100mb downloaded
File1 Downloaded,
File 1 [=============50% ] 50% extracted.
and so on.
note: I am able to show the console outputs as Code below, but would like to use this Progress Bar in my Console APP.
How can I use solution proposed in https://gist.github.com/DanielSWolf/0ab6a96899cc5377bf54 in this case ?
public static void DownloadAndGetFiles()
{
try
{
Parallel.ForEach(FileIds, currentId =>
{
int currentId = FileIds.Id
clientFileDownload(currentId);
});
}
catch (Exception e)
{
}
}
private static void clientFileDownload(int currentId)
{
WebClient client = new WebClient();
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
string downloadedFile = #"d:\tmp\";
client.DownloadFileAsync(new Uri(currentId.URL), downloadedFile); //some URL
while (client.IsBusy) { }
string temp = ExtractAndRename(currentId);
}
private static void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
//Prints: "Downloaded 3mb of 61.46mb (4%)"
Console.WriteLine("Downloaded "
+ ((e.BytesReceived / 1024f) / 1024f).ToString("#0.##") + "mb"
+ " of "
+ ((e.TotalBytesToReceive / 1024f) / 1024f).ToString("#0.##") + "mb"
+ " (" + e.ProgressPercentage + "%)");
}
private static string ExtractAndRename(int currentId)
{
//using SevenZipExtractor lib http://stackoverflow.com/questions/20898794/how-to-extract-files-in-my-archive-one-by-one-using-sevenzipsharp
SevenZipExtractor extractor = new SevenZipExtractor(#"d:\tmp\" + id.Name);
extractor.Extracting += extractor_Extracting;
extractor.ExtractArchive(#"d:\tmp\" + extractName[0]);
return (#"d:\tmp\" + extractName[0]);
}
public static void extractor_Extracting(object sender, SevenZip.ProgressEventArgs p)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.Write("\b\b{0}% Extracted", p.PercentDone);
Console.ResetColor();
}
Provide every thread with a variable y which contains the line number it is allowed to write to.
Before a thread wants to update the screen, create a lock. The console can be used by only one thread at a time. Otherwise results of several threads will mix up.
Move the cursor to line specified by y and update that line.
Release the lock.
An example:
static private readonly object _sync = new object();
private static void UpdateProgress(int y, string item, int progress, int total)
{
int percentage = (int)100.0 * progress / total;
lock(_sync)
{
Console.CursorLeft = 0;
Console.CursorTop = y;
Console.Write(item + " [" + new string('=', percentage / 2) + "] " + percentage + "%");
}
}
You can call this method from your method clientFileDownload, which has to be modified a bit:
private static void clientFileDownload(int currentId, int y)
and should be called when creating the threads like this:
int y = 0;
Parallel.ForEach(FileIds, currentId =>
{
int currentId = FileIds.Id
clientFileDownload(currentId, y);
Interlocked.Increment(ref y);
});
On Windows 10, the System.Drawing.FontFamily.IsStyleAvailable method seems to leave the allocated space into memory even after the Dispose method has been called.
I wrote a simple console application to test it:
using System;
using System.Drawing;
using System.Diagnostics;
namespace ConsoleApplication1
{
class Program
{
static string getMemoryStatusString()
{
using (Process p = Process.GetCurrentProcess())
{
return "(p: " + p.PrivateMemorySize64 + ", v:" + p.VirtualMemorySize64 + ")";
}
}
static void Main(string[] args)
{
string s = getMemoryStatusString();
foreach(FontFamily fontFamily in FontFamily.Families)
{
Console.Write(fontFamily.Name + " " + getMemoryStatusString() + " -> ");
fontFamily.IsStyleAvailable(FontStyle.Regular);
fontFamily.Dispose();
Console.WriteLine(getMemoryStatusString());
}
string e = getMemoryStatusString();
Console.WriteLine(s + " -> " + e);
Console.ReadLine();
}
}
}
Any idea on why this is happening?
Thanks in advance!
If there is a memory leak it would be in gdiplus.dll, FontFamily.IsStyleAvailable() actually makes an extern call to GdipIsStyleAvailable().
From ILSpy:
public bool IsStyleAvailable(FontStyle style)
{
int num2;
int num = SafeNativeMethods.Gdip.GdipIsStyleAvailable(new HandleRef(this, this.NativeFamily), style, out num2);
if (num != 0)
{
throw SafeNativeMethods.Gdip.StatusException(num);
}
return num2 != 0;
}
Which is in turn defined as:
[DllImport("gdiplus.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
internal static extern int GdipIsStyleAvailable(HandleRef family, FontStyle style, out int isStyleAvailable);
I can't see any leak on my workstation (I use Windows 7 with .Net 4.5, however).
There're some issues on the testing procedure
static string getMemoryStatusString() {
// Do not forget to collect the garbage (all the generations)
GC.Collect(2);
GC.WaitForFullGCComplete();
using (Process p = Process.GetCurrentProcess()) {
return "(p: " + p.PrivateMemorySize64 + ", v:" + p.VirtualMemorySize64 + ")";
}
}
// Suspected method
static void methodUnderTest() {
foreach (FontFamily fontFamily in FontFamily.Families) {
//Console.Write(fontFamily.Name + " " + getMemoryStatusString() + " -> ");
fontFamily.IsStyleAvailable(FontStyle.Regular);
//TODO: You must not do this: disposing instanse you don't own
fontFamily.Dispose();
}
}
// Test itself
static void Main(string[] args) {
// Warming up: let all the libraries (dll) be loaded,
// caches fed, prefetch (if any) done etc.
for (int i = 0; i < 10; ++i)
methodUnderTest();
// Now, let's run the test: just one execution more
// if you have a leak, s1 and s2 will be different
// since each run leads to leak of number of bytes
string s1 = getMemoryStatusString();
methodUnderTest();
string s2 = getMemoryStatusString();
Console.Write(s1 + " -> " + s2);
}
And I see that memory before equals to memory after:
(p: 59453440, v:662425600) -> (p: 59453440, v:662425600)
Calling dispose doesn't release manage memory straight away. It has to wait till GC.Collect occurs. If you want to measure memory after Disposing it you should forcefully execute GC.Collect and wait for finalization.
Execute forceful garbage collection as below, before you take after disposing memory reading and see.
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
I am making the game minesweeper and I am trying to implement a highScores feature. I am trying to load 3 different files (each one holds the high scores for each of the 3 difficulty settings) into 3 different richTextBox's. When I run the app and click the 'high scores' tab from the menu strip it works the first time. However if I play a game and then try to access the high scores form I get an Exception error -
An unhandled exception of type 'System.IO.IOException' occurred in
mscorlib.dll
Additional information: The process cannot access the file
'C:\Users\jzcon_000\Copy\Visual
Studio\Projects\Assignment1\Assignment1\bin\Debug\highScoresMed.txt'
because it is being used by another process
This is where the call is made
private void highScoresToolStripMenuItem_Click(object sender, EventArgs e)
{
Minesweeper.HighSc highScore = new Minesweeper.HighSc();
highScore.read();
highScore.Show();
}
This is the method in my HighSc class
public void read()
{
StreamReader readerE = File.OpenText("highScoresEasy.txt");
StreamReader readerM = File.OpenText("highScoresMed.txt");
StreamReader readerH = File.OpenText("highScoresHard.txt");
if (readerE != null)
{
string readEasy = File.ReadAllText("highScoresEasy.txt");
richTextBox1.Text = readEasy;
}
readerE.Close();
if (readerM != null)
{
string readMed = File.ReadAllText("highScoresMed.txt");
richTextBox2.Text = readMed;
}
readerM.Close();
if (readerH != null)
{
string readHard = File.ReadAllText("highScoresHard.txt");
richTextBox3.Text = readHard;
}
readerH.Close();
}
Heres the save high scores class
namespace Minesweeper
{
class Save
{
int diff, hr, min, sec;
string player;
public Save(int difficulty, int hour, int minute, int second, string playerN)
{
diff = difficulty;
hr = hour;
min = minute;
sec = second;
player = playerN;
}
public void save()
{
StreamWriter writerEasy = new StreamWriter("highScoresEasy.txt", true);
StreamWriter writerMed = new StreamWriter("highScoresMed.txt", true);
StreamWriter writerHard = new StreamWriter("highScoresHard.txt", true);
if (diff == 1)
{
writerEasy.WriteLine("Time: " + hr + ":" + min + ":" + sec + " " + "Name: " + player);
writerEasy.Close();
}
else if (diff == 2)
{
writerMed.WriteLine("Time: " + hr + ":" + min + ":" + sec + " " + "Name: " + player);
writerMed.Close();
}
else if (diff == 3)
{
writerHard.WriteLine("Time: " + hr + ":" + min + ":" + sec + " " + "Name: " + player);
writerHard.Close();
}
}
}
}
So when you have the difficulty level set to 1 and then save, you open the StreamWriters for both the level2 and level3 but never close them.
This could only mean that when you try to load the highscore for these two levels you will find your files locked by your previous save.
You should change your Save method to open only the required file
public void save()
{
if (diff == 1)
{
using(StreamWriter writerEasy = new StreamWriter("highScoresEasy.txt", true))
{
writerEasy.WriteLine("Time: " + hr + ":" + min + ":" + sec + " " + "Name: " + player);
}
}
else if (diff == 2)
....
else if (diff == 3)
....
I suggest also to use the using statement in your reading method to be sure that also in case of exceptions the stream are correctly disposed
This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 8 years ago.
So I have my memory class which looks like this:
namespace GeminiCore
{
public class Memory
{
public static int[] memory = new int[256];
public string nextInstruction;
public static int cacheSize = 8;
public CPU myCPU;
public struct frame
{
public bool dirtyBit;
public int isEmpty;
public int value;
public int tag;
public frame(int cacheSize)
{
dirtyBit = false;
isEmpty = 1;
value = 0;
tag = 0;
}
}
public int solveMemory(int value, int instr, frame[] myCache)
{
Console.WriteLine("I reached the solveMemory!!!");
int block = value % cacheSize;
if(instr == 127 || instr == 125 || instr == 124 || instr == 123
|| instr == 122 || instr == 121|| instr == 120)
{
Console.WriteLine("I reached the read section!!!");
if(myCache[block].isEmpty == 0) //Read hit
if(myCache[block].tag == value)
return myCache[block].value;
else
{
myCache[block].value = memory[value]; //Read Miss
myCache[block].tag = value;
myCache[block].isEmpty = 0;
Console.WriteLine("Read Miss --- The Cache is as follows: block = " + block + " the value at this block is: " + myCache[block].value + " the tag at this block is: " + myCache[block].tag);
return myCache[block].value;
}
}
else
{
Console.WriteLine("I reached the write section!!!");
if (myCache[block].isEmpty == 1) //Write Miss
{
Console.WriteLine("Write Miss --- The Cache is as follows: block = " + block + " the value at this block is: " + myCache[block].value + " the tag at this block is: " + myCache[block].tag);
memory[value] = myCPU.ACC;
}
else
{
if (myCache[block].dirtyBit == false)
{
if (myCache[block].tag != value)
{
myCache[block].value = myCPU.ACC; //Write Hit
myCache[block].dirtyBit = true;
myCache[block].tag = value;
Console.WriteLine("Write Hit --- The Cache is as follows: block = " + block + " the value at this block is: " + myCache[block].value + " the tag at this block is: " + myCache[block].tag);
}
}
else
{
memory[myCache[block].tag] = myCache[block].value;
myCache[block].value = myCPU.ACC;
myCache[block].tag = value;
myCache[block].dirtyBit = false;
Console.WriteLine("Write Hit --- The Cache is as follows: block = " + block + " the value at this block is: " + myCache[block].value + " the tag at this block is: " + myCache[block].tag);
}
}
}
return value;
}
}
}
and then I have my CPU class, and I will just post a small snippet of where the error is occurring:
public Memory myMemory;
public static Memory.frame[] myCache = new Memory.frame[Memory.cacheSize];
public void doInstruction()
{
var instr = (finalCodes[i] >> 9) & 127; //Parses op code to find instruction
var immed = (finalCodes[i] >> 8) & 1; //Parses op code to find immediate value
var value = (finalCodes[i] & 255); //Parse op code to find value
foreach (Memory.frame x in myCache)
{
Console.WriteLine("Dirtybit: " + x.dirtyBit + " isEmpty: " + x.isEmpty + " tag: " + x.tag + " value: " + x.value);
}
switch (instr)
{
case (127): //LDA instruction
if (immed == 1)
ACC = value;
else if (immed == 0)
//ACC = Memory.memory[value];
ACC = myMemory.solveMemory(value, instr, myCache);
break;
case (126): //STA instruction
if (immed == 0)
{
Console.WriteLine("The value is: " + value + " The instruction is: " + instr);
foreach (Memory.frame x in myCache)
{
Console.WriteLine("Dirtybit: " + x.dirtyBit + " isEmpty: " + x.isEmpty + " tag: " + x.tag + " value: " + x.value);
}
//Memory.memory[value] = ACC;
myMemory.solveMemory(value, instr, myCache);
}
So here is my problem, when I run my test which takes in assembly code and translates it to binary then runs through the code, when I get to the second command "sta" it should go to the line:
myMemory.solveMemory(value, instr, myCache);
It then gives me a Null Reference Exception when it reaches that point. As you can see I have some command line output to try and see where it is going. It prints out the contents of myCache right before that line. It does not reach any of the debug statements in the solveMemory function however, not even the first one that says:
Console.WriteLine("I reached the solveMemory!!!");
I'm not really sure what is causing this error and I've been looking at it for quite some time. Hopefully one of you will be able to find where exactly I am messing up. Thanks for the time.
public Memory myMemory;
should be:
public Memory myMemory = new Memory();