svn path=/branches/dmsnell/heap-buddy/; revision=63573
This commit is contained in:
dsnell 2006-08-10 03:20:01 +00:00
Родитель ecaf6913fc
Коммит bbfb920bfe
4 изменённых файлов: 246 добавлений и 19 удалений

239
analyzer/GraphReport.cs Normal file
Просмотреть файл

@ -0,0 +1,239 @@
//
// Graph.cs
// based on BacktracesReport.cs
//
//
// BacktracesReport.cs
//
// Copyright (C) 2005 Novell, Inc.
//
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of version 2 of the GNU General Public
// License as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
//
using System;
using System.Collections;
using Cairo;
using Gtk;
namespace HeapBuddy {
public class GraphReport : Report {
public GraphReport () : base ("Graph") { }
public Context Context;
public Gdk.Window Window;
public OutfileReader Reader;
public ArrayList Stamps;
override public void Run (OutfileReader reader, string [] args)
{
Reader = reader;
Stamps = new ArrayList ();
CollectStamps ();
Sort ();
Application.Init ();
Window MainWindow = new Window ("Heap-Buddy");
MainWindow.SetDefaultSize (640, 480);
MainWindow.DeleteEvent += QuitApplication;
VPaned box1 = new VPaned ();
MainWindow.Add (box1);
MenuBar MainMenu = new MenuBar ();
Menu FileMenu = new Menu ();
MenuItem ExitItem = new MenuItem ("E_xit");
ExitItem.Activated += QuitApplication;
FileMenu.Append (ExitItem);
MenuItem FileItem = new MenuItem ("_File");
FileItem.Submenu = FileMenu;
MainMenu.Append (FileItem);
box1.Add (MainMenu);
CairoGraph cg = new CairoGraph (this);
box1.Add (cg);
box1.ResizeChildren ();
MainWindow.ShowAll ();
Application.Run ();
}
public void SetContext (Context c, Gdk.Window w)
{
Context = c;
Window = w;
Continue ();
}
public void Continue ()
{
int x, y, w, h, d;
Window.GetGeometry (out x, out y, out w, out h, out d);
Context c = Context;
if (Stamps.Count <= 0)
return;
c.Color = new Color (1, 1, 1, 1);
c.Paint ();
// Calculate our Time Span, bail if zero
long TimeSpan = ((MemStamp)Stamps [Stamps.Count - 1]).TimeT - ((MemStamp)Stamps [0]).TimeT;
if (TimeSpan == 0)
return;
long LowBytes = ((MemStamp)Stamps [0]).LiveBytes;
long HighBytes = 0;
foreach (MemStamp ms in Stamps) {
if (ms.LiveBytes < LowBytes)
LowBytes = ms.LiveBytes;
if (ms.LiveBytes > HighBytes)
HighBytes = ms.LiveBytes;
}
//*********Scaling
// How much room for the labels?
c.FontSize = 15;
string label = Util.PrettySize (HighBytes);
double GOX = c.TextExtents (label).Width + 15;
double GOY = h - 30;
double GW = w - GOX - 10;
double GH = GOY - 10;
double xscale = (double)TimeSpan / GW;
double yrange = HighBytes - LowBytes;
double yscale = yrange / GH;
// Border
c.Color = new Color (0, 0, 0, 1);
c.LineWidth = 5;
c.Rectangle (GOX, GOY, GW, -GH);
// Memory line
c.MoveTo (GOX, GOY);
long LowTime = ((MemStamp)Stamps [0]).TimeT;
foreach (MemStamp ms in Stamps) {
c.LineTo (GOX + (double)(ms.TimeT - LowTime) / xscale, GOY - (double)(ms.LiveBytes - LowBytes) / yscale);
}
c.LineWidth = 1.5;
c.Stroke ();
// Labels
c.LineWidth = 1;
// Memory
for (int i = 0; i <= 10; i++) {
c.MoveTo (GOX - 5, GOY - i * GH / 10);
c.LineTo (GOX, GOY - i * GH / 10);
c.Stroke ();
label = Util.PrettySize (LowBytes + (i * (long)yrange / 10));
TextExtents e = c.TextExtents (label);
c.MoveTo (GOX - 10 - e.Width, GOY - i * GH / 10 + 0.5 * e.Height);
c.ShowText (label);
}
// Time
for (int i = 0; i < 15; i++) {
c.MoveTo (GOX + i * GW / 15, GOY);
c.LineTo (GOX + i * GW / 15, GOY + 5);
c.Stroke ();
label = Util.PrettyTime (i * TimeSpan / 15);
TextExtents e = c.TextExtents (label);
c.MoveTo (GOX + i * GW / 15 - 0.5 * e.Width, GOY + 15 + e.Height);
c.ShowText (label);
}
}
public class MemStamp {
public long LiveBytes;
public long TimeT;
public MemStamp (long bytes, long time) {
LiveBytes = bytes;
TimeT = time;
}
}
public class MemStampComparer : IComparer {
int IComparer.Compare (System.Object x, System.Object y) {
MemStamp a = (MemStamp)x;
MemStamp b = (MemStamp)y;
if (a.TimeT > b.TimeT) return 1;
else if (a.TimeT < b.TimeT) return -1;
else return 0;
}
}
public void CollectStamps ()
{
foreach (Gc gc in Reader.Gcs) {
Stamps.Add (new MemStamp (gc.PostGcLiveBytes, gc.TimeT));
}
foreach (Resize r in Reader.Resizes) {
Stamps.Add (new MemStamp (r.TotalLiveBytes, r.time_t));
}
}
public void Sort ()
{
IComparer ic = new MemStampComparer ();
Stamps.Sort (ic);
}
protected static void QuitApplication (object o, EventArgs e)
{
Application.Quit ();
}
}
public class CairoGraph : DrawingArea
{
public Cairo.Context Context;
public Gdk.Window Window;
public GraphReport GraphReport;
public CairoGraph (GraphReport gr)
{
GraphReport = gr;
}
protected override bool OnExposeEvent (Gdk.EventExpose args)
{
Window = args.Window;
Context = Gdk.Context.CreateDrawable (Window);
GraphReport.SetContext (Context, Window);
return true;
}
}
}

Просмотреть файл

@ -1,6 +1,6 @@
CSC = mcs -debug
CSFLAGS = -target:exe -r:Mono.Cairo -pkg:gtk-sharp -r:System.Drawing.dll
CSFLAGS = -target:exe -r:Mono.Cairo -pkg:gtk-sharp-2.0 -r:System.Drawing.dll
TARGET = HeapBuddy.exe
WRAPPER = heap-buddy
@ -10,7 +10,8 @@ REPORT_CSFILES = \
HistoryReport.cs \
SummaryReport.cs \
TypesReport.cs \
MemlogReport.cs
MemlogReport.cs \
GraphReport.cs
CSFILES = \
HeapBuddy.cs \
@ -27,7 +28,6 @@ CSFILES = \
MemZone.cs \
TypeLog.cs \
MethodLog.cs \
MemGraph.cs \
Graphics.cs \
$(REPORT_CSFILES)

Просмотреть файл

@ -153,7 +153,7 @@ sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
CSC = mcs -debug
CSFLAGS = -target:exe -r:Mono.Cairo -pkg:gtk-sharp -r:System.Drawing.dll
CSFLAGS = -target:exe -r:Mono.Cairo -pkg:gtk-sharp-2.0 -r:System.Drawing.dll
TARGET = HeapBuddy.exe
WRAPPER = heap-buddy
REPORT_CSFILES = \
@ -161,7 +161,8 @@ REPORT_CSFILES = \
HistoryReport.cs \
SummaryReport.cs \
TypesReport.cs \
MemlogReport.cs
MemlogReport.cs \
GraphReport.cs
CSFILES = \
HeapBuddy.cs \
@ -178,7 +179,6 @@ CSFILES = \
MemZone.cs \
TypeLog.cs \
MethodLog.cs \
MemGraph.cs \
Graphics.cs \
$(REPORT_CSFILES)

Просмотреть файл

@ -203,7 +203,6 @@ namespace HeapBuddy {
Console.WriteLine ("Memlog commands:");
Console.WriteLine (" list: list the items in the current path");
Console.WriteLine (" rows [n]: specify how many rows to print - zero for all");
Console.WriteLine (" graph [filename]: generate graph of memory usage (memlog.png default)");
Console.WriteLine (" help: show this screen");
Console.WriteLine (" quit: quit");
}
@ -277,18 +276,7 @@ namespace HeapBuddy {
i++;
}
break;
case "graph":
string filename = null;
if (i + 1 < cmds.Length)
filename = cmds[++i];
MemGraph graph = new MemGraph (reader, filename);
break;
break;
case "/":
SetPath ("/");