为何GHC Haskell中的空元构造器占用两个机器字?
GHC
closureSize#测量空元构造器的大小疑问 你通过closureSize#做的实验很有意思,先复现你的实验代码和结果:
实验代码
{-# LANGUAGE MagicHash #-} import GHC.Exts import Text.Printf size :: Show a => a -> IO () size !x = printf "sizeof %s = %d\n" (showsPrec 11 x "") (I# (closureSize# x))
实验结果
GHCi> size () sizeof () = 2 GHCi> size (MkSolo 1) sizeof (MkSolo 1) = 2 GHCi> size (1, 2) sizeof (1,2) = 3 GHCi> size (1, 2, 3) sizeof (1,2,3) = 4 GHCi> size Nothing sizeof Nothing = 2 GHCi> size (Just 42) sizeof (Just 42) = 2 GHCi> size [] sizeof [] = 2 GHCi> size [1, 2, 3] sizeof [1,2,3] = 3
疑问解答
你猜的没错——GHC的RTS确实强制要求每个闭包至少占用2个字的内存空间,哪怕是空元构造器也不例外,核心原因有两点:
- 所有闭包的第一个字都是信息表指针,用于垃圾回收、闭包类型判断等核心运行时逻辑。
- 为了简化RTS的实现(比如内存遍历、对齐处理、闭包边界判断),GHC统一规定闭包的最小大小为2个字:空元构造器的第二个字是无意义的填充字,不存储任何有效数据,但必须存在以满足这个最小大小限制。
这个设计避免了RTS需要单独处理“单字闭包”的特殊情况,减少了代码分支,也能保证内存布局的一致性,对垃圾回收等操作的效率有帮助。
内容的提问来源于stack exchange,提问作者Ruifeng Xie
相关产品推荐
相关产品推荐

