相关文章推荐
追风的炒粉  ·  为什么RStudio画图不显示在右下角,显示 ...·  8 月前    · 
刚失恋的煎饼果子  ·  Java ...·  1 年前    · 
老实的毛衣  ·  C++ 中如何遍历对象的成员? - 知乎·  1 年前    · 
阳光的手套  ·  js拦截所有请求_js拦截http请求_丹哥 ...·  1 年前    · 
飞翔的大蒜  ·  Java正则匹配以开头,以}结尾 正则 ...·  1 年前    · 
Code  ›  聊一聊 .NET高级调试 中的一些内存术语开发者社区
程序调试 virtual
https://cloud.tencent.com/developer/article/2368051
痴情的冲锋衣
10 月前
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
 
推荐文章
追风的炒粉  ·  为什么RStudio画图不显示在右下角,显示在一个弹框里面_rstudio画图不出现在右侧-CSDN博客
8 月前
刚失恋的煎饼果子  ·  Java 把object转数组_mob649e8157aaee的技术博客_51CTO博客
1 年前
老实的毛衣  ·  C++ 中如何遍历对象的成员? - 知乎
1 年前
阳光的手套  ·  js拦截所有请求_js拦截http请求_丹哥不是哥的博客-CSDN博客
1 年前
飞翔的大蒜  ·  Java正则匹配以开头,以}结尾 正则 匹配开头_mob6454cc6a68aa的技术博客_51CTO博客
1 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号