Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get available virtual and physical memory size under Mono?

Tags:

.net

clr

mono

Is there any way to get available virtual and physical memory size when running under Mono?

like image 957
user626528 Avatar asked Jun 28 '13 06:06

user626528


1 Answers

You could use this implementation of the "free" command (UNIX) to find out used and available physical memory (it is the best option IMHO):

using System;
using System.Text.RegularExpressions;
using System.IO;

namespace FreeCSharp
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            FreeCSharp free = new FreeCSharp();
            free.GetValues();

            long buffersPlusCached = free.Buffers + free.Cached;
            long mainUsed = free.MemTotal - free.MemFree;

            // What you would get from free command:
            Console.WriteLine("-/+ buffers/cache:    {0}     {1}", (mainUsed - buffersPlusCached), (free.MemFree + buffersPlusCached));

            // What means:
            Console.WriteLine("Used physical memory: {0} kB", mainUsed - buffersPlusCached);
            Console.WriteLine("Available physical memory: {0} kB", free.MemFree + buffersPlusCached);
        }
    }

    /// <summary>
    /// FreeCSharp: quick implementation of free command (kind of) using C#
    /// </summary>
    public class FreeCSharp
    {
        public long MemTotal { get; private set; }
        public long MemFree { get; private set; }
        public long Buffers { get; private set; }
        public long Cached { get; private set; }

        public void GetValues()
        {
            string[] memInfoLines = File.ReadAllLines(@"/proc/meminfo");

            MemInfoMatch[] memInfoMatches =
            {
                new MemInfoMatch(@"^Buffers:\s+(\d+)", value => Buffers = Convert.ToInt64(value)),
                new MemInfoMatch(@"^Cached:\s+(\d+)", value => Cached = Convert.ToInt64(value)),
                new MemInfoMatch(@"^MemFree:\s+(\d+)", value => MemFree = Convert.ToInt64(value)),
                new MemInfoMatch(@"^MemTotal:\s+(\d+)", value => MemTotal = Convert.ToInt64(value))
            };

            foreach (string memInfoLine in memInfoLines)
            {
                foreach (MemInfoMatch memInfoMatch in memInfoMatches)
                {
                    Match match = memInfoMatch.regex.Match(memInfoLine);
                    if (match.Groups[1].Success)
                    {
                        string value = match.Groups[1].Value;
                        memInfoMatch.updateValue(value);
                    }
                }
            }
        }

        public class MemInfoMatch
        {
            public Regex regex;
            public Action<string> updateValue;

            public MemInfoMatch(string pattern, Action<string> update)
            {
                this.regex = new Regex(pattern, RegexOptions.Compiled);
                this.updateValue = update;
            }
        }
    }
}

Alternatively, it could be used sysconf (UNIX) to get the currently available pages of physical memory. This value depends on how many data the OS has cached, because of that, you should execute echo 3 > /proc/sys/vm/drop_caches before running this code:

using System;
using Mono.Unix.Native;

OperatingSystem os = Environment.OSVersion;
PlatformID pid = os.Platform;
if (pid == PlatformID.Unix || pid == PlatformID.MacOSX) {
    long pages = Syscall.sysconf (SysconfName._SC_AVPHYS_PAGES);
    long page_size = Syscall.sysconf (SysconfName._SC_PAGESIZE);
    Console.WriteLine("The number of currently available pages of physical memory: {0}, Size of a page in bytes: {1} bytes", pages, page_size);
    Console.WriteLine("Mem: {0} bytes", pages * page_size);
 }
like image 106
Gooseman Avatar answered Nov 15 '22 07:11

Gooseman