public static MemorySnapshot FromProcess(int processId)
        {
            MemorySnapshot memorySnapshot = new MemorySnapshot();

            Process process = Process.GetProcessById(processId);

            process.Refresh();

            PROCESS_MEMORY_COUNTERS_EX counters = MemoryInterop.GetCounters(process.Handle);

            memorySnapshot.GdiObjectCount            = NativeMethods.GetGuiResources(process.Handle, NativeMethods.GR_GDIOBJECTS);
            memorySnapshot.HandleCount               = process.HandleCount;
            memorySnapshot.PageFileBytes             = counters.PagefileUsage;
            memorySnapshot.PageFilePeakBytes         = counters.PeakPagefileUsage;
            memorySnapshot.PoolNonpagedBytes         = counters.QuotaNonPagedPoolUsage;
            memorySnapshot.PoolPagedBytes            = counters.QuotaPagedPoolUsage;
            memorySnapshot.ThreadCount               = process.Threads.Count;
            memorySnapshot.UserObjectCount           = NativeMethods.GetGuiResources(process.Handle, NativeMethods.GR_USEROBJECTS);
            memorySnapshot.VirtualMemoryBytes        = process.VirtualMemorySize64;
            memorySnapshot.VirtualMemoryPrivateBytes = counters.PrivateUsage;
            memorySnapshot.WorkingSetBytes           = process.WorkingSet64;
            memorySnapshot.WorkingSetPeakBytes       = process.PeakWorkingSet64;
            memorySnapshot.WorkingSetPrivateBytes    = MemoryInterop.GetPrivateWorkingSet(process);
            memorySnapshot.Timestamp = DateTime.Now;

            return(memorySnapshot);
        }
        /// <summary>
        /// De-Serializes a MemorySnapshot instance from xml format.
        /// </summary>
        /// <param name="rootNode">The Xml Node from which the MemorySnapshot is to be de-serialized.</param>
        /// <returns>MemorySnapshot instance.</returns>
        internal static MemorySnapshot Deserialize(XmlNode rootNode)
        {
            MemorySnapshot result = new MemorySnapshot();

            result.GdiObjectCount            = (long)DeserializeNode(rootNode, "GdiObjectCount");
            result.HandleCount               = (long)DeserializeNode(rootNode, "HandleCount");
            result.PageFileBytes             = DeserializeNode(rootNode, "PageFileBytes");
            result.PageFilePeakBytes         = DeserializeNode(rootNode, "PageFilePeakBytes");
            result.PoolNonpagedBytes         = DeserializeNode(rootNode, "PoolNonpagedBytes");
            result.PoolPagedBytes            = DeserializeNode(rootNode, "PoolPagedBytes");
            result.ThreadCount               = (long)DeserializeNode(rootNode, "ThreadCount");
            result.UserObjectCount           = (long)DeserializeNode(rootNode, "UserObjectCount");
            result.VirtualMemoryBytes        = (long)DeserializeNode(rootNode, "VirtualMemoryBytes");
            result.VirtualMemoryPrivateBytes = DeserializeNode(rootNode, "VirtualMemoryPrivateBytes");
            result.WorkingSetBytes           = (long)DeserializeNode(rootNode, "WorkingSetBytes");
            result.WorkingSetPeakBytes       = (long)DeserializeNode(rootNode, "WorkingSetPeakBytes");
            result.WorkingSetPrivateBytes    = (long)DeserializeNode(rootNode, "WorkingSetPrivateBytes");

            XmlNode timestampNode = rootNode.SelectSingleNode("Timestamp");

            if (timestampNode == null)
            {
                throw new XmlException("MemorySnapshot file is missing value: Timestamp");
            }

            XmlAttribute timestampAttribute = timestampNode.Attributes["Value"];

            result.Timestamp = DateTime.ParseExact(timestampAttribute.InnerText, "yyyy-MM-ddTHH:mm:ss.fffffffUzzz", CultureInfo.InvariantCulture);

            XmlNode timeDiffNode = rootNode.SelectSingleNode("TimeDiff");

            if (timeDiffNode != null)
            {
                XmlAttribute timeDiffAttribute = timeDiffNode.Attributes["Value"];
                result.TimeDiff = TimeSpan.Parse(timestampAttribute.InnerText);
            }

            return(result);
        }
        /// <summary>
        /// Compares the current MemorySnapshot instance to the specified MemorySnapshot to produce a difference.
        /// </summary>
        /// <param name="memorySnapshot">The MemorySnapshot to be compared to.</param>
        /// <returns>A new MemorySnapshot object representing the difference between the two memory snapshots (i.e. the result of the comparison).</returns>
        public MemorySnapshot CompareTo(MemorySnapshot memorySnapshot)
        {
            MemorySnapshot diff = new MemorySnapshot();

            diff.GdiObjectCount            = this.GdiObjectCount - memorySnapshot.GdiObjectCount;
            diff.HandleCount               = this.HandleCount - memorySnapshot.HandleCount;
            diff.PageFileBytes             = new IntPtr(this.PageFileBytes.ToInt64() - memorySnapshot.PageFileBytes.ToInt64());
            diff.PageFilePeakBytes         = new IntPtr(this.PageFilePeakBytes.ToInt64() - memorySnapshot.PageFilePeakBytes.ToInt64());
            diff.PoolNonpagedBytes         = new IntPtr(this.PoolNonpagedBytes.ToInt64() - memorySnapshot.PoolNonpagedBytes.ToInt64());
            diff.PoolPagedBytes            = new IntPtr(this.PoolPagedBytes.ToInt64() - memorySnapshot.PoolPagedBytes.ToInt64());
            diff.ThreadCount               = this.ThreadCount - memorySnapshot.ThreadCount;
            diff.UserObjectCount           = this.UserObjectCount - memorySnapshot.UserObjectCount;
            diff.VirtualMemoryBytes        = this.VirtualMemoryBytes - memorySnapshot.VirtualMemoryBytes;
            diff.VirtualMemoryPrivateBytes = new IntPtr(this.VirtualMemoryPrivateBytes.ToInt64() - memorySnapshot.VirtualMemoryPrivateBytes.ToInt64());
            diff.WorkingSetBytes           = this.WorkingSetBytes - memorySnapshot.WorkingSetBytes;
            diff.WorkingSetPeakBytes       = this.WorkingSetPeakBytes - memorySnapshot.WorkingSetPeakBytes;
            diff.WorkingSetPrivateBytes    = this.WorkingSetPrivateBytes - memorySnapshot.WorkingSetPrivateBytes;
            diff.TimeDiff  = this.Timestamp - memorySnapshot.Timestamp;
            diff.Timestamp = this.Timestamp;

            return(diff);
        }