Chrome堆快照结构字段释义及ArrayBuffer提取相关技术咨询
堆快照元数据字段含义
基础统计字段
snapshot 根下的顶层统计字段:
node_count:堆快照包含的内存节点总数量,本次快照共6182075个节点edge_count:节点之间的引用关系总条数,本次快照共17793245条引用trace_function_count:本次快照关联的栈跟踪函数数量,值为0说明本次快照未开启内存分配栈采样
node_fields(内存节点字段定义)
node_fields 规定了每个内存节点的属性顺序,node_types 对应每个位置的属性值类型:
- 第0位
type:值为node_types第0项枚举数组中的类型,包括hidden(引擎内部隐藏节点)、array(数组/缓冲类节点)、string(字符串)、object(普通对象)、code(可执行代码)、closure(闭包)、regexp(正则)、number(数字)、native(原生宿主对象)、synthetic(合成节点)、concatenated string(拼接字符串)、sliced string(切片字符串)、symbol(符号类型)、bigint(大整数) - 第1位
name:类型为字符串,节点的可读名称,比如对象的构造函数名、字符串的内容预览 - 第2位
id:类型为数字,节点的全局唯一标识,全快照不重复 - 第3位
self_size:类型为数字,节点自身占用的内存大小(单位字节),不包含它引用的其他节点的内存 - 第4位
edge_count:类型为数字,该节点向外发起的引用边总数量 - 第5位
trace_node_id:类型为数字,关联的栈跟踪节点ID,未开采样时默认值为0 - 第6位
detachedness:类型为数字,标记节点是否脱离DOM树,0为正常挂载,1为已脱离但未被GC回收的游离节点
edge_fields(引用边字段定义)
每条引用边代表一个节点对另一个节点的引用关系,edge_types 对应每个位置的属性值类型:
- 第0位
type:值为edge_types第0项枚举数组中的类型,包括context(上下文引用)、element(数组元素引用)、property(对象属性引用)、internal(JS引擎内部引用)、hidden(隐藏引用)、shortcut(快捷引用)、weak(弱引用) - 第1位
name_or_index:类型为字符串或数字,引用的标识:对象属性对应属性名,数组元素对应下标数字 - 第2位
to_node:类型为节点ID,指向被引用的目标节点的id值
其他可选字段
本次快照未开启栈采样,以下字段无实际数据:
trace_function_info_fields:栈跟踪的函数信息字段,存储函数ID、函数名、所属脚本名、脚本ID、行号、列号trace_node_fields:调用栈节点字段,存储调用节点ID、关联函数索引、调用次数、分配内存大小、子节点索引sample_fields:内存分配采样的时间戳、对应分配的节点IDlocation_fields:对象分配位置字段,存储对象索引、所属脚本ID、分配时的代码行号、列号
从堆快照提取目标数据的方法
堆快照的实际业务数据是扁平化的大数组,按元数据规则解析即可:
- 先解析
nodes数组:每7个元素为一组,对应node_fields的7个属性,把所有节点转换为结构化对象,同时建立id到节点的映射表方便快速查询 - 再解析
edges数组:每3个元素为一组,对应edge_fields的3个属性,把所有引用边关联到发起引用的源节点上 - 最后按需求过滤:根据类型、大小、名称、引用关系等条件筛选目标节点,再通过关联的引用边查找上下游关联数据
检索已知大小唯一的ArrayBuffer的方法
完全可以检索到,操作步骤如下:
- 先过滤所有
type为array的节点,ArrayBuffer在堆快照中对应的节点类型就是array - 匹配
self_size和你已知的ArrayBuffer大小:ArrayBuffer的内容直接存储在自身节点内,它的self_size就是实际分配的字节数,和你已知的大小完全对应 - 因为你确认大小唯一,过滤后得到的节点就是目标ArrayBuffer
- 如果需要提取它的存储内容,可以通过该节点的
element类型引用边,直接拿到每一位的数值内容
内容的提问来源于stack exchange,提问作者Light Steel
相关产品推荐
相关产品推荐

