『随笔』.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(左右)
分类:
练手片段调错
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 单线程的Redis速度为什么快?
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
2017-12-03 『练手』通过注册表 获取 VS 和 SQLServer 文件路径