相关文章推荐
儒雅的碗  ·  从iOS应用程序扩展发出网络请求会返回错误: ...·  3 月前    · 
很拉风的西红柿  ·  pipx 卸载poetry - CSDN文库·  1 年前    · 
跑龙套的小狗  ·  vs2015如何安装vsix扩展工具_无法确 ...·  1 年前    · 
想旅行的野马  ·  本次运行允许和仅在使用中允许-掘金·  1 年前    · 
豪情万千的松鼠  ·  如何用代码让电脑蓝屏 - 抖音·  2 年前    · 
Code  ›  聊一聊 .NET高级调试 中的一些内存术语开发者社区
程序调试 virtual
https://cloud.tencent.com/developer/article/2368051
痴情的冲锋衣
1 年前
JusterZhu

聊一聊 .NET高级调试 中的一些内存术语

前往小程序,Get 更优 阅读体验!
立即前往
腾讯云
开发者社区
文档 建议反馈 控制台
首页
学习
活动
专区
工具
TVP
最新优惠活动
文章/答案/技术大牛
发布
首页
学习
活动
专区
工具
TVP 最新优惠活动
返回腾讯云官网
JusterZhu
首页
学习
活动
专区
工具
TVP 最新优惠活动
返回腾讯云官网
社区首页 > 专栏 > 聊一聊 .NET高级调试 中的一些内存术语

聊一聊 .NET高级调试 中的一些内存术语

作者头像
JusterZhu
发布 于 2023-12-06 15:44:25
164 0
发布 于 2023-12-06 15:44:25
举报
文章被收录于专栏: JusterZhu

一:背景

1. 讲故事

在高级调试的旅程中,经常会有一些朋友问我什么是 工作集(内存) ,什么是 提交大小 ,什么是 Virtual Size , 什么是 Working Set 。。。截图如下:

既然有很多朋友问,这些用口头也不怎么好描述,刚好上午有时间就系统的聊一下吧。

二:内存术语解读

1. Virtual Size 是什么

可能有些朋友知道,内存中的虚拟地址被划分成了三类。

  • Reserved (预定地址)
  • Committed (提交地址)
  • Free (蛮荒地址)

上面的 预定+提交 就是我们的 Virtual Size,即 Virtual Size = Reserved + Committed 。

当然口说无凭,得要拿出证据,写一个 x86 的 C# 测试代码,参考如下:

代码语言: javascript
复制

        static void Main(string[] args)
            Console.WriteLine("hello world!");
            Console.ReadLine();

将程序跑起来后用 windbg 附加,使用 !address -summary 将计算出的内存和 Process Explorer 工具显示的 Virtual Size 进行对比,截图如下:

有些较真的朋友可能说:Explorer 显示出的是 163.300 ,而 windbg 显示的是 163.281 ,为什么还差一点点,其实这是不同工具的统计误差,仅此而已。

2. Working Set

有些朋友可能知道,一个程序所占的内存最终会在三个地方落地:

  • 物理内存条
  • 虚拟内存 pagefile
  • 物理文件 MappedFile

这里的 Workding Set 特指的就是 物理内存条 ,由于 Windows 有 MappedFile 这种文件映射(内存共享)机制,所以物理内存条上的内存可以进一步划分为 自己独占的 + 大家共享的 ,可能有些朋友比较蒙,截个图如下:

有了这张图的基础,转化为专业术语就是:

  • Workding Set = WS Private + WS Shareable

最后我们还是用 Explorer 观察下刚才的 C# 程序,截图如下:

3. Private Bytes

刚才我们说到了内存最终会落地到三个地方,其中一个地方就是 虚拟内存(pagefile) ,简而言之它的作用就是给物理内存打辅助,这个 pagefile.sys 默认是在 C 盘上,截图如下:

有了这些基础,就可以列出一个公式了。

  • Private Bytes = WS Private + Pages Out (pagefile)

上面的 Pages Out 是我定义的换页内存,这个 Private Bytes 指标在分析内存泄露的场景下特别有用,它能够准备的洞察当前程序是否存在大量的 Pages Out(换页内存) 。

为了方便演示出现了大量的换页内存,写一个不断灌数据的例子。

代码语言: javascript
复制

    internal class Program
        static void Main(string[] args)
            var list = new List<string>();
            for (int i = 0; i < 100000000; i++)
                list.Add(string.Join(",", Enumerable.Range(0, 100000)));
                if (i % 10000 == 0) { Console.WriteLine($"i={i}"); }
            Console.WriteLine("成功!");
            Console.ReadLine();

将程序跑起来后,截图如下:

根据刚才的计算公式: Pages Out = Private Bytes - WS Private ,可以得知大概有 29G 不得不存放在 pagefile 中。

本来想用 wmic pagefile get /value 看一下当前机器的虚拟内存占用,发现有时候不准,我也没太深究了,输出如下:

代码语言: javascript
复制

C:\Users\Administrator>wmic pagefile get /value
AllocatedBaseSize=49464
Caption=C:\pagefile.sys
CurrentUsage=1473
Description=C:\pagefile.sys
InstallDate=20230807095038.481750+480
 
推荐文章
儒雅的碗  ·  从iOS应用程序扩展发出网络请求会返回错误:“找不到具有指定主机名的服务器”-腾讯云开发者社区-腾讯云
3 月前
很拉风的西红柿  ·  pipx 卸载poetry - CSDN文库
1 年前
跑龙套的小狗  ·  vs2015如何安装vsix扩展工具_无法确定操作。必须指定vsix的安装路径-CSDN博客
1 年前
想旅行的野马  ·  本次运行允许和仅在使用中允许-掘金
1 年前
豪情万千的松鼠  ·  如何用代码让电脑蓝屏 - 抖音
2 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号