mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-09-22 20:45:27 -04:00
Merge pull request #3172 from lightpanda-io/js_mem_gauge
metrics: Add js memory gauge
This commit is contained in:
5 files changed
+38
-1
No files matched your search
+3
-1
@@ -128,7 +128,9 @@ fn shrank(self: *Arena, n: usize) void {
|
||||
}
|
||||
|
||||
fn resized(self: *Arena, old_len: usize, new_len: usize) void {
|
||||
if (new_len >= old_len) self.grew(new_len - old_len) else self.shrank(old_len - new_len);
|
||||
// self.bytes always contains old_len, so this can't wrap
|
||||
self.bytes = self.bytes - old_len + new_len;
|
||||
lp.metrics.arena_memory_bytes.add(@as(i64, @intCast(new_len)) - @as(i64, @intCast(old_len)));
|
||||
}
|
||||
|
||||
const vtable = Allocator.VTable{
|
||||
|
||||
@@ -34,6 +34,7 @@ arena_miss: CounterEnum("size", @import("ArenaPool.zig").BucketSize) = .{},
|
||||
arena_inflight: GaugeEnum("size", @import("ArenaPool.zig").BucketSize) = .{},
|
||||
arena_memory_bytes: Gauge = .{},
|
||||
navigate: CounterEnum("type", @import("telemetry/telemetry.zig").Event.Navigate.Context) = .{},
|
||||
js_heap_physical_bytes: Gauge = .{},
|
||||
js_heap_size_bytes: Histogram(&.{
|
||||
4 * 1024 * 1024,
|
||||
8 * 1024 * 1024,
|
||||
@@ -91,6 +92,7 @@ const help = .{
|
||||
.arena_inflight = "Arenas currently checked out of the pool. Above the bucket's max, every acquisition is a miss and every release is discarded",
|
||||
.arena_memory_bytes = "Backing memory held by pooled arenas, including capacity retained on the free list",
|
||||
.navigate = "Navigations by initiating frame type",
|
||||
.js_heap_physical_bytes = "V8 heap physical size summed over every live isolate (one per CDP connection).",
|
||||
.js_heap_size_bytes = "V8 heap physical size, sampled when a page is closed",
|
||||
.http_requests = "HTTP requests submitted, by dispatch mode (excludes internal requests like robots.txt)",
|
||||
.http_status = "Final HTTP response status category (redirects counted once, at the final hop)",
|
||||
@@ -160,6 +162,13 @@ const Gauge = struct {
|
||||
_ = @atomicRmw(isize, &self.value, .Sub, @intCast(n), .monotonic);
|
||||
}
|
||||
|
||||
// For callers that track an absolute value and report the change since
|
||||
// their last report. There's no set(): the gauge is a sum over threads,
|
||||
// so a caller can only move its own contribution.
|
||||
pub fn add(self: *Gauge, n: i64) void {
|
||||
_ = @atomicRmw(isize, &self.value, .Add, @intCast(n), .monotonic);
|
||||
}
|
||||
|
||||
fn write(self: *const Gauge, comptime name: []const u8, comptime help_text: []const u8, writer: *std.Io.Writer) !void {
|
||||
try writer.writeAll("# HELP " ++ name ++ " " ++ help_text ++ "\n" ++ "# TYPE " ++ name ++ " gauge\n");
|
||||
try writer.print(name ++ " {d}\n", .{@atomicLoad(isize, &self.value, .monotonic)});
|
||||
|
||||
@@ -53,6 +53,9 @@ selector_cache: Selector.Cache,
|
||||
// Pinned-arena bytes we haven't told v8 about yet
|
||||
arena_account: lp.Arena.Account = .{},
|
||||
|
||||
// Our isolate's heap size as of the last reportJsHeap().
|
||||
last_reported_js_bytes: usize = 0,
|
||||
|
||||
// Permission state set via CDP Browser.grantPermissions / setPermission /
|
||||
// resetPermissions, keyed by permission name (e.g. "geolocation"). Read back
|
||||
// by navigator.permissions.query(). Scoped to the Browser so it persists
|
||||
@@ -139,6 +142,10 @@ pub fn deinit(self: *Browser) void {
|
||||
const allocator = self.allocator;
|
||||
|
||||
self.closeSession();
|
||||
|
||||
lp.metrics.js_heap_physical_bytes.add(-@as(i64, @intCast(self.last_reported_js_bytes)));
|
||||
self.last_reported_js_bytes = 0;
|
||||
|
||||
// After this returns, the watchdog thread holds no reference to our env
|
||||
// or http_client — required before either is torn down.
|
||||
self.app.watchdog.unregister(&self.watchdog_entry);
|
||||
@@ -210,6 +217,12 @@ pub fn flushArenaMemory(self: *Browser) void {
|
||||
self.env.isolate.adjustAmountOfExternalAllocatedMemory(delta);
|
||||
}
|
||||
|
||||
pub fn reportJsHeap(self: *Browser) void {
|
||||
const bytes = self.env.isolate.getHeapStatistics().total_physical_size;
|
||||
lp.metrics.js_heap_physical_bytes.add(@as(i64, @intCast(bytes)) - @as(i64, @intCast(self.last_reported_js_bytes)));
|
||||
self.last_reported_js_bytes = bytes;
|
||||
}
|
||||
|
||||
pub fn runMicrotasks(self: *Browser) void {
|
||||
self.env.runMicrotasks();
|
||||
}
|
||||
|
||||
@@ -472,6 +472,11 @@ pub fn init(self: *Frame, frame_id: u32, page: *Page, opts: InitOpts) !void {
|
||||
}.runIdleTasks, 200, .{ .name = "frame.runIdleTasks", .blocks_done = false });
|
||||
}
|
||||
}
|
||||
|
||||
if (parent == null) {
|
||||
// no point reporting this for each child page
|
||||
session.browser.reportJsHeap();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Frame) void {
|
||||
@@ -543,6 +548,9 @@ pub fn deinit(self: *Frame) void {
|
||||
const browser = page.session.browser;
|
||||
|
||||
browser.http_client.abortOwner(&self._http_owner);
|
||||
if (self.parent == null) {
|
||||
browser.reportJsHeap();
|
||||
}
|
||||
|
||||
browser.env.destroyContext(self.js);
|
||||
|
||||
@@ -1228,6 +1236,10 @@ pub fn documentIsComplete(self: *Frame) void {
|
||||
error.JsException => {}, // already logged
|
||||
else => log.err(.frame, "document is complete", .{ .err = err, .type = self._type, .url = self.url }),
|
||||
};
|
||||
|
||||
if (self.parent == null) {
|
||||
self._session.browser.reportJsHeap();
|
||||
}
|
||||
}
|
||||
|
||||
fn _documentIsComplete(self: *Frame) !void {
|
||||
|
||||
@@ -206,6 +206,7 @@ pub fn deinit(self: *Page) void {
|
||||
|
||||
const session = self.session;
|
||||
lp.metrics.js_heap_size_bytes.observe(session.browser.env.isolate.getHeapStatistics().total_physical_size);
|
||||
session.browser.reportJsHeap();
|
||||
defer session.browser.env.memoryPressureNotification(.moderate);
|
||||
|
||||
self.identity.deinit();
|
||||
|
||||
Reference in new issue
Block a user