test: 新增内存占用基准用例与留存内存采集

bench 每轮采集在 workload 后 promote 根持有/会话引用的 epoch 对象并强制
一次 full GC,新增 peak_bytes / retained_bytes / retained_objects 三口径
(原 session_* 字段为执行期累计分配,不反映 workload 后留存);dispatch
循环增加 session 堆高水位采样,VM 暴露 session_bytes_peak 与
collect_session_gc。新增 8 个 mem_* 压力用例(对象图/字符串/闭包链/数组
增删/跨调用保留/Map/Set 保留/字符串拼接),基线扩至 76 条目。
This commit is contained in:
root
2026-09-10 08:18:52 +00:00
parent 31d3f59d2b
commit 1b87e212f9
20 changed files with 1359 additions and 697 deletions
+8
View File
@@ -0,0 +1,8 @@
// 数组增缩容量:填满 200000 元素后截回 1000,观测容量是否回落
// 堆账目按元素 Vec capacity 计——截短后若不收缩,留存账目仍反映大容量
var arr = [];
for (var i = 0; i < 200000; i++) {
arr[i] = i * 3 + 1;
}
arr.length = 1000;
arr.length
+17
View File
@@ -0,0 +1,17 @@
// 闭包/upvalue 长链留存:10000 层闭包,每层同时捕获前层闭包与自身 payload 对象,
// 自 head 沿 prev 链回溯第一层时全部驻留(函数对象、upvalue cell、payload 串)
var head = null;
for (var i = 0; i < 10000; i++) {
(function (prev, payload) {
head = function () {
return [prev, payload];
};
})(head, { id: i, data: "closure_payload_padding_" + i });
}
var cur = head;
var hops = 0;
while (cur !== null) {
cur = cur()[0];
hops++;
}
hops === 10000
+12
View File
@@ -0,0 +1,12 @@
// 跨调用长存活数据:全局 store 经 30000 次函数调用累积 30000 条记录,
// 记录在函数内构造、写出 global 后跨帧存活(session 堆)
var store = { records: [], total: 0 };
function logRecord(tag, value) {
var r = { seq: store.total, tag: tag, value: value };
store.records.push(r);
store.total++;
}
for (var i = 0; i < 30000; i++) {
logRecord("tag_" + (i % 16), "record_payload_" + i);
}
store.records.length
+7
View File
@@ -0,0 +1,7 @@
// 原生盒边持有:Map 持 20000 组字符串键 + 对象值,
// 键串与值对象(及其 payload 串)全部经 Map 原生盒边驻留
var m = new Map();
for (var i = 0; i < 20000; i++) {
m.set("map_key_" + i, { id: i, data: "map_value_payload_" + i });
}
m.size
+16
View File
@@ -0,0 +1,16 @@
// 大型对象图留存:15 层满二叉树共 32767 个节点,顶层 root 整体驻留 session 堆
// 每节点 id 唯一(免意外共享),内节点带 left/right 子引用,叶节点带 leaf 标记
function makeNode(depth, base) {
if (depth === 0) {
return { id: base, leaf: 1 };
}
return {
id: base,
depth: depth,
left: makeNode(depth - 1, base * 2),
right: makeNode(depth - 1, base * 2 + 1),
};
}
var root = makeNode(14, 1);
root.left.id + root.right.right.id
+7
View File
@@ -0,0 +1,7 @@
// 原生盒边持有:Set 持 20000 个对象,每个对象带 payload 字符串,
// 全部经 Set 原生盒边驻留
var s = new Set();
for (var i = 0; i < 20000; i++) {
s.add({ id: i, data: "set_value_payload_" + i });
}
s.size
+7
View File
@@ -0,0 +1,7 @@
// 字符串累积留存:40000 个互不相同的字符串驻留数组
// 内容由索引推导(无去重可合并),数组本身经顶层 var 驻留
var pool = [];
for (var i = 0; i < 40000; i++) {
pool[i] = "str_" + i + "_" + (i * 7 % 997) + "_padding_padding_padding";
}
pool.length
+10
View File
@@ -0,0 +1,10 @@
// 拼接 rope 链留存:对 200 字节字面量重复二元拼接,形成深 Cons 链
// 每链节点账目按拼接逻辑长度计,报告值高于实际字节足迹;
// 链自顶层 var 驻留,节点地址稳定不搬移
var piece =
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
var chain = "seed_seed_seed";
for (var i = 0; i < 1000; i++) {
chain = chain + piece;
}
chain.length