You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何lazy_static!变量在符号表中的大小为0?

关于lazy_static生成的HashMap符号大小为0的疑问

测试代码

#[macro_use]
extern crate lazy_static;

use std::collections::HashMap;

lazy_static! {
    static ref HASHMAP: HashMap<u32, &'static str> = {
        let mut m = HashMap::new();
        m.insert(0, "foo");
        m.insert(1, "bar");
        m.insert(2, "baz");
        m
    };
}

fn main() {
    // 第一次访问`HASHMAP`时触发初始化
    println!("The entry for `0` is \"{}\".", HASHMAP.get(&0).unwrap());

    // 后续访问直接返回已初始化完成的值
    println!("The entry for `1` is \"{}\".", HASHMAP.get(&1).unwrap());
}

符号表查看结果

执行命令:readelf -sW target/debug/deps/section_test-4d7d6a03c56fdde3.o

输出:

Symbol table '.symtab' contains 590 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
452: 0000000000000000     0 OBJECT  LOCAL  DEFAULT  498 _ZN12section_test7HASHMAP17hbc6de818c577d166E

可以看到HASHMAP对应的符号大小为0。

段信息查看结果

执行命令:readelf -SW target/debug/deps/section_test-4d7d6a03c56fdde3.o

输出:

There are 527 section headers, starting at offset 0x98690:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
 [498] .rodata._ZN12section_test7HASHMAP17hbc6de818c577d166E PROGBITS        0000000000000000 00b528 000000 00   A  0   0  1

该符号位于rodata段中,对应段的大小也为0。

疑问与解答

疑问

既然长度为0,是否意味着无法存储数据?HashMap的内存在运行时分配在何处?

解答

符号大小为0不代表无法存储数据,这是lazy_static!宏的实现特性导致的:

  • lazy_static!生成的HASHMAP本质是一个初始化占位符,编译期它仅标记初始化逻辑的入口,不会把HashMap的实际数据写入可执行文件的静态段,所以符号表和对应rodata段的大小都显示为0。
  • 当程序第一次访问HASHMAP时,会触发你定义的初始化闭包,此时才会在堆内存上动态分配空间,构建并填充HashMap实例。
  • 后续所有对HASHMAP的访问,都会直接返回已初始化完成的堆上实例,避免重复执行初始化逻辑。

简单来说,这个符号只是负责触发初始化的"开关",实际的数据全在运行时分配的堆内存里,和静态段无关。


内容的提问来源于stack exchange,提问作者super_jh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 01:25:28