Add "Memory" tab to lg

shell_global_get_memory_info() is a new function which extracts a few
global counters we have already, namely glibc's mallinfo, spidermonkey's
JSGC_BYTES, and gjs' counters for boxed/object/etc wrappers.

There is some slight overlap with perf; ultimately though I'd
like this function to do some more extensive analysis, so it wouldn't
be quite the same.

perf is going to be mainly concerned with how big the whole process
over time is; memory_info is for debugging memory leaks.

https://bugzilla.gnome.org/show_bug.cgi?id=650692
This commit is contained in:
Colin Walters 2011-05-20 15:50:54 -04:00
parent bb0f76f562
commit aa03734d39
3 changed files with 102 additions and 0 deletions

View File

@ -582,6 +582,53 @@ ErrorLog.prototype = {
} }
}; };
function Memory() {
this._init();
}
Memory.prototype = {
_init: function() {
this.actor = new St.BoxLayout({ vertical: true });
this._glibc_uordblks = new St.Label();
this.actor.add(this._glibc_uordblks);
this._js_bytes = new St.Label();
this.actor.add(this._js_bytes);
this._gjs_boxed = new St.Label();
this.actor.add(this._gjs_boxed);
this._gjs_gobject = new St.Label();
this.actor.add(this._gjs_gobject);
this._gjs_function = new St.Label();
this.actor.add(this._gjs_function);
this._gjs_closure = new St.Label();
this.actor.add(this._gjs_closure);
this._gcbutton = new St.Button({ label: 'Full GC',
style_class: 'lg-obj-inspector-button' });
this._gcbutton.connect('clicked', Lang.bind(this, function () { global.gc(); this._renderText(); }));
this.actor.add(this._gcbutton, { x_align: St.Align.START,
x_fill: false });
this.actor.connect('notify::mapped', Lang.bind(this, this._renderText));
},
_renderText: function() {
if (!this.actor.mapped)
return;
let memInfo = global.get_memory_info();
this._glibc_uordblks.text = 'glibc_uordblks: ' + memInfo.glibc_uordblks;
this._js_bytes.text = 'js bytes: ' + memInfo.js_bytes;
this._gjs_boxed.text = 'gjs_boxed: ' + memInfo.gjs_boxed;
this._gjs_gobject.text = 'gjs_gobject: ' + memInfo.gjs_gobject;
this._gjs_function.text = 'gjs_function: ' + memInfo.gjs_function;
this._gjs_closure.text = 'gjs_closure: ' + memInfo.gjs_closure;
}
};
function Extensions() { function Extensions() {
this._init(); this._init();
} }
@ -764,6 +811,9 @@ LookingGlass.prototype = {
this._errorLog = new ErrorLog(); this._errorLog = new ErrorLog();
notebook.appendPage('Errors', this._errorLog.actor); notebook.appendPage('Errors', this._errorLog.actor);
this._memory = new Memory();
notebook.appendPage('Memory', this._memory.actor);
this._extensions = new Extensions(); this._extensions = new Extensions();
notebook.appendPage('Extensions', this._extensions.actor); notebook.appendPage('Extensions', this._extensions.actor);

View File

@ -25,6 +25,11 @@
#include <meta/display.h> #include <meta/display.h>
#include <meta/util.h> #include <meta/util.h>
/* Memory report bits */
#ifdef HAVE_MALLINFO
#include <malloc.h>
#endif
#include "shell-enum-types.h" #include "shell-enum-types.h"
#include "shell-global-private.h" #include "shell-global-private.h"
#include "shell-jsapi-compat-private.h" #include "shell-jsapi-compat-private.h"
@ -1126,6 +1131,38 @@ shell_global_maybe_gc (ShellGlobal *global)
gjs_context_maybe_gc (global->js_context); gjs_context_maybe_gc (global->js_context);
} }
/**
* shell_global_get_memory_info:
* @global:
* @meminfo: (out caller-allocates): Output location for memory information
*
* Load process-global data about memory usage.
*/
void
shell_global_get_memory_info (ShellGlobal *global,
ShellMemoryInfo *meminfo)
{
JSContext *context;
memset (meminfo, 0, sizeof (meminfo));
#ifdef HAVE_MALLINFO
{
struct mallinfo info = mallinfo ();
meminfo->glibc_uordblks = info.uordblks;
}
#endif
context = gjs_context_get_native_context (global->js_context);
meminfo->js_bytes = JS_GetGCParameter (JS_GetRuntime (context), JSGC_BYTES);
meminfo->gjs_boxed = (unsigned int) gjs_counter_boxed.value;
meminfo->gjs_gobject = (unsigned int) gjs_counter_object.value;
meminfo->gjs_function = (unsigned int) gjs_counter_function.value;
meminfo->gjs_closure = (unsigned int) gjs_counter_closure.value;
}
/** /**
* shell_global_notify_error: * shell_global_notify_error:
* @global: a #ShellGlobal * @global: a #ShellGlobal

View File

@ -90,6 +90,21 @@ void shell_global_get_pointer (ShellGlobal *global,
void shell_global_gc (ShellGlobal *global); void shell_global_gc (ShellGlobal *global);
void shell_global_maybe_gc (ShellGlobal *global); void shell_global_maybe_gc (ShellGlobal *global);
typedef struct {
guint glibc_uordblks;
guint js_bytes;
guint gjs_boxed;
guint gjs_gobject;
guint gjs_function;
guint gjs_closure;
} ShellMemoryInfo;
void shell_global_get_memory_info (ShellGlobal *global,
ShellMemoryInfo *meminfo);
gboolean shell_global_set_property_mutable (ShellGlobal *global, gboolean shell_global_set_property_mutable (ShellGlobal *global,
const char *object, const char *object,
const char *property, const char *property,