编辑修复了一些细节:四边形是 8 个字节并解释了静态链接字段。
我认为这unsafeSizeOf
是不准确的,你误解了它的输出。请注意,它仅显示顶级闭包的内存使用情况,而不是对象的总空间使用情况。我认为,您所看到的是,除了元组之外还需要 10 个字节q
(而除了boxed和 boxed之外还需要 10 个字节)。此外,我的测试表明顶级构造函数实际上每个都需要 24 个字节(在 64 位架构上),尽管我也报告了 10 个字节。p
p
Char
Int
unsafeSizeOf
特别是,如果我stack ghc -- -fforce-recomp -ddump-asm -dsuppress-all -O2 ZeroMemory.hs
使用 GHC 8.0.2 编译以下测试程序:
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeFamilies #-}
module ZeroMemory where
data Uncurry (a :: i -> j -> *) (z :: (i, j)) =
forall x y . z ~ '(x,y) => Uncurry !(a x y)
q :: Uncurry (,) '(Int, Char)
q = Uncurry (0, '\0')
r :: Uncurry (,) '(Int, Char)
r = Uncurry (1, '\1')
那么顶级q
闭包的内存占用如下所示:
q_closure:
.quad Uncurry_static_info
.quad $s$WUncurry_$d~~_closure+1
.quad q1_closure+1
.quad 3
注意.quad
这里的每个实际上是8个字节;它是旧式 16 位“字”的“四边形”。我相信quad
这里的最后一个值为 3,是GHC 实现注释中描述的“静态链接字段” ,因此不适用于“典型”堆分配对象。
所以,忽略这个 final 字段,顶层q
闭包的总大小是 24 个字节,它指的是q1_closure
代表包含的元组:
q1_closure:
.quad (,)_static_info
.quad q3_closure+1
.quad q2_closure+1
.quad 3
另外 24 个字节。
q2
和q3
闭包是装箱的,Int
因此Char
每个占用两个四边形(16字节)。因此,q
总共占用 10 个四边形,即 80 个字节。(我将r
其作为健全性检查包括在内,以确保我没有误认任何共享信息。)
一个p
元组本身的内存占用相当于q1_closure
7 个四边形或 56 个字节。