PerfView专题 (第九篇):洞察 C# 中的 LOH 内存碎片化
一:背景
在 内存泄漏
的系列问题中,有一类问题是 内存碎片化
导致的,而且这种更容易发生在 LOH 上,因为它默认不开启 对象压缩
,一般遇到这种情况,优先让朋友执行下面的代码应急。
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();
后续再研究问题根源,这篇我们就来聊一聊如何用 PerfView
神器帮助我们寻找 内存碎片化
的根源。
二:碎片化洞察
1. WinDbg 的局限
为了方便讲述,先上一段造成 LOH内存碎片化
的测试代码。
internal class Program
{
static void Main(string[] args)
{
Test();
Console.ReadLine();
}
public static List<byte[]> list = new List<byte[]>();
static void Test()
{
for (int i = 0; i < 50000; i++)
{
if (i % 2 == 0)
{
list.Add(new byte[85000 * 2]);
list[i] = null;
}
else
{
list.Add(new byte[85000]);
}
}
Console.WriteLine("5w 数据插入完毕!");
}
}
代码逻辑非常简单,就是间隔释放其中的 byte[]
对象,让 Free 和 Live 对象成交错状, 可以用 WinDbg 观察如下:
0:009> !dumpheap
Address MT Size
...
00000000f0cd6028 000000000050ff60 170088 Free
00000000f0cff890 00007ffdb4a25490 85024
00000000f0d144b0 000000000050ff60 170088 Free
00000000f0d3dd18 00007ffdb4a25490 85024
00000000f0d52938 000000000050ff60 170088 Free
00000000f0d7c1a0 00007ffdb4a25490 85024
00000000f0d90dc0 000000000050ff60 170088 Free
00000000f0dba628 00007ffdb4a25490 85024
00000000f0dcf248 000000000050ff60 170088 Free
00000000f0df8ab0 00007ffdb4a25490 85024
00000000f0e0d6d0 000000000050ff60 170088 Free
00000000f0e36f38 00007ffdb4a25490 85024
00000000f0e4bb58 000000000050ff60 170088 Free
00000000f0e753c0 00007ffdb4a25490 85024
00000000f0e89fe0 000000000050ff60 170088 Free
00000000f0eb3848 00007ffdb4a25490 85024
00000000f0ec8468 000000000050ff60 170088 Free
00000000f0ef1cd0 00007ffdb4a25490 85024
00000000f0f068f0 000000000050ff60 170088 Free
00000000f0f30158 00007ffdb4a25490 85024
00000000f0f44d78 000000000050ff60 170088 Free
...
虽然用 WinDBG 可以轻松找出,但这里有一个非常大的局限,就是你不知道 Free 对象生前是什么东西,往往这时候就只能用 db,dc,du 看内存地址,在无计可施的情况下, PerfView 就可以大显威龙了。
2. PerfView 洞察
接下来我们打开PerfView,采用默认设置启动收集,稍等之后,点击 Memory -> GCStats
项,观察 LOH Frag %
列,如下图所示:
从图中的 LOH Frag %
列可以看出碎片化确实蛮高的,接下来我们就是找 Free 块生前是什么东西,如果能记录到 Free
生成是由谁分配的那该有多好呀!!!
哈哈,在 PerfView 中还真有这么一个视图叫 Gen 2 Object Deaths Stacks
,如下图所示:
从名字上就能看到,这个视图记录的是 LOH 上那些已经死亡对象的生前 Stack,当然了,这是按权重计算的,如果是 Event 模式产生的就好了,那会记录所有的对象分配。
接下来双击 Gen 2 Object Deaths Stacks
再选中我们的应用程序,可以看到权重占比最高的是 System.Byte[]
对象,如下图所示:
接下来右键点击 Goto -> Goto Item in Callers
按钮,可以看到占比最高的是 Program.Test()
分配所致,高达 9396 个,如下图所示:
接下来就是调研 Program.Test()
方法,找出最后被 Free 的原因, 这就是 PerfView 和 WinDbg 双剑合璧的威力。
PerfView专题 (第九篇):洞察 C# 中的 LOH 内存碎片化的更多相关文章
- Egret入门学习日记 --- 第九篇(书中 2.7~2.8节 内容)
第九篇(书中 2.7~2.8节 内容) 昨天记录到了 2.6节 ,那么今天就从 2.7节 开始. 这个 2.7节 有7个小段,有点长,总结一下重点: 1.调试项目的两种方法. 2.运行项目的两种窗口选 ...
- PerfView专题 (第二篇):如何寻找 C# 中的 Heap堆内存泄漏
一:背景 上一篇我们聊到了如何去找 热点函数,这一篇我们来看下当你的程序出现了 非托管内存泄漏 时如何去寻找可疑的代码源头,其实思路很简单,就是在 HeapAlloc 或者 VirtualAlloc ...
- PerfView专题 (第一篇):如何寻找热点函数
一:背景 准备开个系列来聊一下 PerfView 这款工具,熟悉我的朋友都知道我喜欢用 WinDbg,这东西虽然很牛,但也不是万能的,也有一些场景他解决不了或者很难解决,这时候借助一些其他的工具来辅助 ...
- Pytorch_第九篇_神经网络中常用的激活函数
神经网络中常用的激活函数 Introduce 理论上神经网络能够拟合任意线性函数,其中主要的一个因素是使用了非线性激活函数(因为如果每一层都是线性变换,那有啥用啊,始终能够拟合的都是线性函数啊).本文 ...
- PerfView专题 (第十一篇):使用 Diff 功能洞察 C# 内存泄漏增量
一:背景 去年 GC架构师 Maoni 在 (2021 .NET 开发者大会) [https://ke.segmentfault.com/course/1650000041122988/section ...
- PerfView专题 (第十二篇):对 C# 下的 SDK 类库进行监控(大结局)
一:背景 本篇是我们系列文章的最后一篇,前面的文章中大多是在 CLR Runtime 以及 OS 层面进行监控来发现各种可疑的程序问题,除了这两个层面,其实我们还可以对 SDK 中一些类进行洞察,比如 ...
- 第九篇 Flask 中的蓝图(BluePrint)
第九篇 Flask 中的蓝图(BluePrint) 蓝图,听起来就是一个很宏伟的东西 在Flask中的蓝图 blueprint 也是非常宏伟的 它的作用就是将 功能 与 主服务 分开怎么理解呢? ...
- Flask最强攻略 - 跟DragonFire学Flask - 第九篇 Flask 中的蓝图(BluePrint)
蓝图,听起来就是一个很宏伟的东西 在Flask中的蓝图 blueprint 也是非常宏伟的 它的作用就是将 功能 与 主服务 分开怎么理解呢? 比如说,你有一个客户管理系统,最开始的时候,只有一个查看 ...
- 解剖SQLSERVER 第九篇 OrcaMDF现在能通过系统DMVs显示元数据(译)
解剖SQLSERVER 第九篇 OrcaMDF现在能通过系统DMVs显示元数据(译) http://improve.dk/orcamdf-now-exposes-metadata-through-s ...
随机推荐
- 从单例谈double-check必要性,多种单例各取所需
theme: fancy 前言 前面铺掉了那么多都是在讲原则,讲图例.很多同学可能都觉得和设计模式不是很搭边.虽说设计模式也是理论的东西,但是设计原则可能对我们理解而言更加的抽象.不过好在原则东西不是 ...
- 『忘了再学』Shell基础 — 25、扩展正则表达式
目录 1.扩展正则表达式说明 2.练习 (1)+和?练习 (2)|和()练习 3.注意(重点) 1.扩展正则表达式说明 熟悉正则表达式的童鞋应该很疑惑,在其他的语言中是没有扩展正则表达式说法的,在Sh ...
- 字节开源RPC框架Kitex的日志库klog源码解读
前言 这篇文章将着重于分析字节跳动开源的RPC框架Kitex的日志库klog的源码,通过对比Go原生日志库log的实现,探究其作出的改进. 为了平滑学习曲线,我写下了这篇分析Go原生log库的文章,希 ...
- 开发工具-在线JSON相关的工具
更新记录: 2022年6月7日 新增链接. 2022年6月1日 开始. https://www.sojson.com/json2entity.html URL参数互转JSON https://tool ...
- 皓远的第一次博客作业(pta题目集——1-3)
题目集总结: 前言: 一. 知识点运用: ① Java入门的基础语法(循环,判断,字符串,数组等等),Java的基础类运用,类与对象关系调用,类间关系(聚合). ② 引(类与对象): 对象 ...
- 『忘了再学』Shell流程控制 — 35、多分支case条件语句
目录 1.case条件语句介绍 2.case语句需要注意的内容 3.练习 示例1 示例2 1.case条件语句介绍 case语句和if-elif-else语句一样都是多分支条件语句,不过和if多分支条 ...
- hadoop集群搭建——单节点(伪分布式)
1. 准备工作: 前提:需要电脑安装VM,且VM上安装一个Linux系统 注意:本人是在学习完尚学堂视频后,结合自己的理解,在这里做的总结.学习的视频是:大数据. 为了区分是在哪一台机器做的操作,eg ...
- 用python做个计算器不是轻轻松松吗~
计算器 Kivy是一个免费的开源Python库,可以快速轻松地开发高度交互的跨平台应用程序. 这里我将使用Python中的Kivy包来构建一个计算器GUI.(https://jq.qq.com/?_w ...
- Banner自定义图案
Banner大全https://www.bootschool.net/ascii
- 我是如何将一个老系统的kafka消费者服务的性能提升近百倍的
☞☞☞ 我是如何将一个老系统的kafka消费者服务的性能提升近百倍的 ☜☜☜ ○○○○○○○○○○○○○○○ 大家好,又见面了~ kafka作为一种高吞吐量的分布式发布订阅消息系统,在业务系统中被广泛 ...