public string ComputeMemory(int intervals, bool fDumpRanges) { bool fFilterProcesses = itparms.EnableProcessFilter; StringWriter sw = new StringWriter(); var mem = new MemProcessor(this); ETWLineReader l = StandardLineReader(); long tDelta = (l.t1 - l.t0) / intervals; long tStart = l.t0; long tNext = l.t0 + tDelta; int iInterval = 0; bool fOut = false; MemEffect effect = new MemEffect(); foreach (ByteWindow b in l.Lines()) { if (l.t > tNext && iInterval < intervals - 1) { if (!mem.IsEmpty) { fOut = true; DumpRangeTime(sw, tStart, tNext); sw.WriteLine(mem.Dump()); } mem.Reset(); tStart = tNext; tNext += tDelta; } if (l.idType != mem.idAlloc && l.idType != mem.idFree) { continue; } if (fFilterProcesses && !l.MatchingProcess()) { continue; } if (!l.MatchingTextFilter()) { continue; } if (!l.MatchingMemory()) { continue; } mem.ProcessMemRecord(l, b, effect); } if (!mem.IsEmpty) { fOut = true; DumpRangeTime(sw, tStart, l.t1); sw.WriteLine(mem.Dump()); } sw.WriteLine(mem.DumpMemoryPlots()); if (fOut) { if (fDumpRanges) { sw.WriteLine(); sw.WriteLine(mem.DumpRanges()); } } else { sw.WriteLine("No activity"); } lastMemProcessor = mem; return(sw.ToString()); }
public void ProcessMemRecord(ETWLineReader l, ByteWindow b, MemEffect memeffect) { // empty the net effect of this record memeffect.released = memeffect.reserved = memeffect.committed = memeffect.decommitted = 0; int interval = (int)((l.t - l.t0) / (double)(l.t1 - l.t0) * memoryPlotColumns); // the above can overflow because time ranges might be out of order so clamp any overflows // also we have to handle the case where l.t == l.t1 which would otherwise overflow if (interval < 0) { interval = 0; } if (interval >= memoryPlotColumns) { interval = memoryPlotColumns - 1; } bT.Assign(b, fldProcessNamePID).Trim(); int idProcess = trace.atomsProcesses.Lookup(bT); // bogus process, disregard if (idProcess == -1) { return; } MemInfo p = memInfos[idProcess]; var rsReserved = p.rsReserved; var rsCommitted = p.rsCommitted; ulong addrBase = b.GetHex(fldMemBaseAddr); ulong addrEnd = b.GetHex(fldMemEndAddr); b.Field(fldFlags).Trim(); if (l.idType == idAlloc) { if (b.StartsWith(byReserveCommit)) { memeffect.reserved = rsReserved.AddRange(addrBase, addrEnd); p.cbReserved += memeffect.reserved; p.reservedDistribution[interval] += (long)memeffect.reserved; if (memeffect.reserved != 0) { p.cReserved++; } memeffect.committed = rsCommitted.AddRange(addrBase, addrEnd); p.cbCommitted += memeffect.committed; p.committedDistribution[interval] += (long)memeffect.committed; if (memeffect.committed != 0) { p.cCommitted++; } } else if (b.StartsWith(byReserve)) { memeffect.reserved = rsReserved.AddRange(addrBase, addrEnd); p.cbReserved += memeffect.reserved; p.reservedDistribution[interval] += (long)memeffect.reserved; if (memeffect.reserved != 0) { p.cReserved++; } } else if (b.StartsWith(byCommit)) { memeffect.committed = rsCommitted.AddRange(addrBase, addrEnd); p.cbCommitted += memeffect.committed; p.committedDistribution[interval] += (long)memeffect.committed; if (memeffect.committed != 0) { p.cCommitted++; } } } if (l.idType == idFree) { if (b.StartsWith(byRelease)) { memeffect.decommitted = rsCommitted.RemoveRange(addrBase, addrEnd); p.cbDecommitted += memeffect.decommitted; p.committedDistribution[interval] -= (long)memeffect.decommitted; if (memeffect.decommitted != 0) { p.cDecommitted++; } memeffect.released = rsReserved.RemoveRange(addrBase, addrEnd); p.cbReleased += memeffect.released; p.reservedDistribution[interval] -= (long)memeffect.released; if (memeffect.released != 0) { p.cReleased++; } } else if (b.StartsWith(byDecommit)) { memeffect.decommitted = rsCommitted.RemoveRange(addrBase, addrEnd); p.cbDecommitted += memeffect.decommitted; p.committedDistribution[interval] -= (long)memeffect.decommitted; if (memeffect.decommitted != 0) { p.cDecommitted++; } } } }