『随笔』.Net 底层 数组[] 的 基本设计探秘 512 子数组
1 static void Main(string[] args) 2 { 3 Console.ReadKey(); 4 5 //初始化数组 不会立即开辟内存字节, 只有实际给数组赋值时 才会开辟内存 6 // 7 //猜测数组内部的实现原理如下: 8 // 9 // > 数组内部 还有一个 数组集合 10 // > 赋值时, 会通过索引找到 对应的那个 数组集合的子数组, 然后初始化这个 子数组 11 // > 取值时, 如果索引对应的 子数组还没有创建, 则直接返回 NULL 12 // 13 // > 经过下面代码的 测算, 子数组的长度为 512 左右 14 // > 比如: 你初始化一个 2048 个元素的数组, 数组内部其实开辟了 4个子数组 15 // 16 // > 下面的 array 和 array2, 17 // 前者 i=i+1 肯定会 初始化每一个 子数组 18 // 后者 i=i+512 会跳跃定位 子数组 19 // > 最后 array 和 array2 占用内存一样多 —— 即: 跳跃 512 依然完成了全部子数组的初始化 20 21 22 23 object[] array = new object[20 * 1024 * 1024]; //NULL 每个占 8 字节 总内存 173M 24 for (int i = 0; i < array.Length; i = i + 1) 25 array[i] = null; 26 27 object[] array2 = new object[20 * 1024 * 1024]; 28 for (int i = 0; i < array2.Length; i = i + 512) //i=i+1 i=i+512 最后开辟的内存是一样多的 (索引跳跃512 就会定位到 下一个子数组, 然后初始化这个 子数组) 29 array2[i] = null; 30 31 32 //int[] array3 = new int[20 * 1024 * 1024]; //Int32 每个占 4 字节 33 //for (int i = 0; i < array3.Length; i = i + 1) 34 // array3[i] = 1; 35 36 37 38 Console.ReadKey(); 39 40 }
测试代码 比较简单。
32位程序,启动时 8M,
开辟 object[] 数组,全部赋值 NULL,内存飙到 173M
object 在 数组中的指针 占 8 字节
通过跳跃赋值, 得出结论:
数组内部 包含 若干个 子数组, 子数组 固定长度 512(左右)