Performance Optimization:使用 ETW 和 PerfView 分析 .NET 应用性能

前言

在开发 .NET 应用时,无论是 Web 应用还是桌面应用,优化应用的性能是非常重要的。因为一些不良的性能问题可能带来很多负面影响,比如:

  • 用户体验差,无法满足用户需求
  • 服务器压力大,导致响应变慢或崩溃
  • 应用内存泄漏,导致性能逐渐下降,最终 crash

因此,我们需要对应用进行全面的性能优化,如调整代码结构、异步化处理等方式,但是如何找到最慢的代码,哪些操作的性能需要优化是优化的前提。

本文将介绍一种跨平台的 ETW 工具,它名为 PerfView,它可以帮助开发人员解决应用程序的性能问题。我们将展示 PerfView 如何在 .NET 应用程序中使用,以及一些性能分析和优化的技巧。

ETW 是什么?

ETW,全称为事件跟踪(Event Tracing for Windows),是一种通过内核轮询收集操作系统和应用程序事件的技术。在Windows中,ETW是性能收集器和诊断经常使用的工具。与常见的跟踪技术(例如CPU采样)相比,ETW性能好,对应用程序的影响较小。

PerfView是一种跨平台的ETW分析工具,它可以通过 .NET Framework 上的 EventSource 机制和 .NET Core 上的 EventPipe 机制来收集事件,选择依据数据分析中所需的信息。

PerfView是什么?

PerfView 是一个免费的 ETW 分析工具。它可以建立一个“事件记录器”,收集和分析应用程序和操作系统的运行事件。它是一个 Microsoft 出品的工具,虽然专为 Windows 平台开发,但可以用来分析运行在任何 .NET 平台上的应用程序。它的主要特点如下:

  • 可以轻松地捕获事件,并显示相关的数据
  • 在数据捕获期间,具有极低的开销
  • 解析的事件数据可以查看与可视化。

使用这个工具可以帮助我们定位最慢的代码,查找瓶颈等信息,以便进行正确的应用程序处理。

尽管 PerfView 主要是为 .NET 应用程序开发者设计的(.NET Framework 和 .NET Core), 但也可以用于分析其他类型的应用程序或操作系统,只需调整 PerfView 的设置,以获取适当的事件记录器。

PerfView 基本原理

PerfView 提供了一种 ETW 模型,它可以从操作系统和应用程序中捕获事件。由于平均每个正常应用程序的 ETW 日志输出非常多,因此需要一种强大的性能分析工具来处理这些事件。

使用 PerfView,你将能够:

  • 创建、启动、停止和取消 perflog 抓取。
  • 扫描并导出 perflog 文件。
  • 收集和分析日志产生的事件。查找其中的瓶颈,进行优化。

常用的 PerfView 功能之一是抓取可以测试性能的应用程序的 standard event counting 数据。标准事件计数是指从 EVENT_TRACE_TYPE_GUID_COUNT 所指定的 Windows 标准事件提供程序中捕获的事件数据。这些数据与 PermView 预配置的规则一起,可以成为性能计数数据的一个好基础。

PerfView 还提供了一些强大而简单的功能来帮助开发人员的性能分析工作,例如:

  • 产生拥有完整文件名和行号的性能曲线
  • 应用程序线程聚合和堆栈采集
  • GC 和 Azure 即用型 VM 事件和收集

PerfView 基本使用

安装 PerfView

首先,你需要先下载并安装 PerfView 。安装时请不要忘记在安装向导中勾选“Install Windows Performance Toolkit ”。

创建 PerfLog 文件

Step1:打开 PerfView 工具

打开 PerfView,点击页面左下角的“+”(或 File 菜单下的“New Session”)。

Step2:开始捕捉事件并记录 PerfLogs

确认后,将会开始捕获相关的 ETW 事件,它们将被记录在文件中(PerfLogs)。

您可以使用本地浏览器访问循环 HTTP 请求来生成一些数据,例如 https://localhost:44363/ (如果您使用的是 Visual Studio)。

Step3:End Event Source

在 PerfView Recorder 中勾选“End Event Source”将会暂停这次记录,将抽样数据从内存中写入到 PerfLogs 中:

导入 PerfNet.dll

默认情况下,PerfView会导入 Microsoft-Windows-DotNETRuntime,但可能会忽略其他 DLL 和检测性能日志的更多事件。

针对 ASP.NET Core 应用程序,需要手动导入 PerfNet.dll 模块:

提示:如果 PerfNet.dll 不在让您选择它的列表中,请将其手动添加到记录器中,方法是使用“添加子附加计数器”菜单项来添加。

使用方法

在 PerfView 工具中,我们可以使用很多操作进行性能分析。下面介绍使用其中三种常用的操作:Mark, Time Line, GC View。

① Mark 操作

Mark 操作(事件标记)实际上就是给源代码中的行位置打个标记。以这个标记为起点,分析器就可以根据这个标记分析代码的性能。

例如,在 Web 应用代码中,下列代码的性能分析:

------ ------------ ----------------
-
    --- -- - --- ------------
    -----------

    -- ---- ---- ----

    ----------
    ------------------- - -----------
    ------ -------
-

我们可以在这个时间流中添加 Mark(标记),以便对行为进行分析。

打开主界面并启动 PerfView,单击“Mark”按钮。此时,将在开始的时间点处创建一个新的标记:

选择“Mark”,输入事件名称并单击“Enter”。New Mark 将被创建并显示在新标签页上:

步骤如下:

  • 选定 “Trace” 菜单下的“Mark”。
  • 在“New Markers”选项卡中输入需要的事件名称。
  • 按下ENTER以创建。

② Time Line 操作

Time Line 操作(时序线)是一种按时间顺序展示的操作内容。该操作可用于查看应用程序中的事件。Time Line 操作是所有 ETW 分析工具中最重要的操作之一。

在 PerfView 中,用户可以创建时间轴视图,以轻松找到应用程序运行中的性能瓶颈,以及专注于事件的细节和异常。

例如,在 Web 应用代码中,下面这段代码的性能分析:

------ ------------ ----------------
-
    --- -- - --- ------------
    -----------

    -- ---- ---- ----

    ----------
    ------------------- - -----------
    ------ -------
-

我们可以在这个时间流中添加Mark(标记),以便对行为进行分析:

使用“Time Line”功能,将显示下图所示的时间轴视图:

  • 使用时间轴图标缩放图像。
  • 右键单击事件并使用上下文菜单执行更多任务。
  • 可以使多个时间轴基于新的“StartTime”和“Duration”时间窗口排序,并记住鼠标所在的位置。

③ GC View 操作

PerView 还提供了 GC(垃圾回收) View 功能,让你可以检查 CLR(共同语言运行库)中的垃圾对象。在利用了 GC View 操作后,PerfView 还提供了完整的明细信息,让你查看及分析回收垃圾的机制,这个操作对于优化内存很有帮助。

例如,给出以下 C# 代码:

----- -------
----- -----------------

--------- ---------------
-
  ----- ------------
  -
    ------ ---- ------------- -----
    -
      -- ------ - ----- -- ------- -- ----- ---- ---
      --- --- - --- -----------
      ----- ------ -
        --- ----------- - -------------------------

        -- ---- ---------- ---- -- ----- ---- --------- -- -----
        --- ------- - --- --------------- - -------------------------------------

        -- -- --------- ---- --
        ---------- - --

        -- ----- --- ----- ---- -- - ----- -- -- --- --- ---- -- ----- --
        -- --------------------- - -- -- -- -
          -- ---- -- --- --- --- --- ------ ----- - --- --- -- -- ---- -- -----------
          -----------------------------
        -
      -
    -
  -
-

使用下列命令数组,运行 gcexp.exe 于上图的命令环境中:

-------
---------------------------------------------

在 PerfView 工具中,选中“GC View”,将显示如下的结果:

PerfView 进阶运用

当基于 PerfView 的记录器来进行分析时,必须收集并分析相应的事件,如 Allocation、GC、JIT 等。这些已经发出的事件被存储在 ETL 文件中。这些文件可以通过选择文件,以及设置事件过滤器来控制记录什么。为了在 PerfView 中分析收集的事件,它必须首先读入响应的 ETL 文件。

分析已收集的事件时,字面上我们可以很明显地看到收集的应用程序,这些程序是有序以时间的形式组织的。这使我们能够专注于每个事件的详细细节,对照时间轴解决一些问题。

PerfView 中有许多用于分析 .NET 应用程序的工具和技术,可以使您轻松定位应用程序的性能瓶颈。

总结

在本文中,我们介绍了一种跨平台的 ETW 工具,名为 PerfView。我们展示了 PerfView 如何在 .NET 应用程序中使用,以及一些性能分析和优化的技巧。通过学习 PerfView 的的使用方法,您可以找到慢代码、观察堆内存、识别之间的链式调用以及基于请求清理的性能问题。PerfView 是性能优化的重要工具之一,它可以帮助我们找到应用程序中的性能瓶颈。使用它可以使我们的程序性能得到显著提升。

来源:JavaScript中文网 ,转载请联系管理员! 本文地址:https://www.javascriptcn.com/post/647c28ac968c7c53b0750cc5


猜你喜欢

  • Mongoose 中的更新时钩子详解

    Mongoose 是一个基于 Node.js 的 MongoDB 驱动程序,它提供了一种简洁的方式来定义和操作 MongoDB 的文档。其中,Mongoose 还提供了一系列的钩子函数,使我们可以在执...

    1 年前
  • 利用 RxJS 实现自定义 debounce 函数

    在前端开发中,我们经常会遇到需要对用户的输入进行防抖处理的场景,以避免频繁地触发请求或其他操作。而 RxJS 是一个强大的响应式编程库,其中的 debounce 操作符可以方便地实现防抖功能。

    1 年前
  • 如何在 Mocha 测试中测试 WebSockets 通信

    WebSockets 是 HTML5 中的一种新协议,它是一种创建长连接的技术,使得浏览器与服务器之间的实时双向通信变得简单易行。在开发 WebSockets 应用时,我们需要对其进行测试,以确保它们...

    1 年前
  • 在 Vue.js 中使用 Element-UI 的坑点注意事项

    在Vue.js中使用Element-UI是一种非常常见的方式,但是在实际使用过程中,我们可能会遇到一些坑点,需要特别注意。本文将介绍一些在Vue.js中使用Element-UI时需要注意的坑点,并给出...

    1 年前
  • Socket.io 和 NestJS 结合实现 WebSocket 服务

    在现代 web 应用程序中,实时数据的传输变得越来越重要。WebSocket 技术提供了一种实时双向通讯的方式,能够大大改善传输速度,节省资源。但是,使用原生 WebSocket API 进行开发需要...

    1 年前
  • 利用函数式编程提高 JavaScript 程序性能

    前言 在 JavaScript 中,函数式编程是一种广泛使用的编程范式。它强调函数的纯粹性和不变性,通过合理地利用 JavaScript 的闭包和高阶函数特性来实现高度抽象和可复用的代码。

    1 年前
  • 使用 Node.js 和 Axios 进行 HTTP 请求管理

    随着前端应用程序在规模和复杂性上的不断增加,管理 HTTP 请求变得越来越重要。Node.js 和 Axios 是两个用于处理 HTTP 请求的非常流行的工具。在本文中,我们将详细介绍如何使用 Nod...

    1 年前
  • Angular 模板语法的基本使用

    引言 在前端开发中,Angular 是一种流行的 JavaScript 框架,它提供了一种叫做模板语法的技术,能够在 HTML 中添加逻辑和动态绑定属性。本篇文章将介绍 Angular 模板语法的基本...

    1 年前
  • React 中的服务端渲染及使用方法

    React 是一个用于构建用户界面的 JavaScript 库,其流行度已经超过了其他类似库和框架。在前端开发中,React 经常被用于构建单页应用程序(SPA),但它也可以用于服务端渲染(SSR)。

    1 年前
  • CSS Grid 实战 demo

    CSS Grid 是一种新的网格布局方式,它可以快速简便地构建复杂的网页布局。相比传统的布局方式,如 float、position 等,CSS Grid 具有更好的可读性、可维护性和灵活性。

    1 年前
  • Next.js 中的 Redux 和 React-Redux 使用指南

    最近,越来越多的前端开发人员倾向于在项目中使用状态管理库来帮助管理复杂的应用程序状态。Redux 和 React-Redux 是 React 生态系统中最受欢迎的状态管理库之一。

    1 年前
  • ES8 中的 async/await

    在前端开发中,经常需要进行异步操作,例如从后端获取数据或者进行网络请求等等。在 ES6 中,Promise 出现了,解决了异步操作中回调函数嵌套的问题,使代码具有更好的可读性。

    1 年前
  • Redis 缓存穿透的原因及解决技巧

    缓存穿透的定义 缓存穿透是指访问缓存和数据库时,请求的数据均不在缓存和数据库中,导致反复查询数据库,增加系统压力和延迟的现象。 缓存穿透的原因 缓存穿透主要由以下原因引起: 请求数据在缓存和数据库中...

    1 年前
  • Custom Elements 如何修改根据属性动态创建的 HTML 元素

    在前端领域,Custom Elements 是一种强大的 Web Component 技术,用于创建自定义的 HTML 元素和组件。Custom Elements 可以允许开发者将现有的 HTML 标...

    1 年前
  • 解决 TypeScript 中重载时函数实现不匹配的问题

    在 TypeScript 中,重载是一种非常有用的特性,它允许我们为同一个函数提供多个不同的签名。这样一来,函数就能根据传入的参数类型或数量不同而执行不同的逻辑。 然而,在实现重载时,我们需要注意一个...

    1 年前
  • Flexbox 解决宽度不一致的两栏布局问题

    在前端开发的过程中,我们经常会遇到需要实现宽度不一致的两栏布局的情况,比如左侧菜单栏宽度固定,右侧内容区域宽度根据屏幕变化而自适应。在传统布局中,我们可能需要使用 float 或者 display:i...

    1 年前
  • 如何在 Docker 容器中使用 GPU 加速计算?

    随着深度学习技术的发展,越来越多的应用需要使用到 GPU 进行计算。而 Docker 作为一个流行的容器化解决方案,也面临着对 GPU 支持的需求。本文将介绍如何在 Docker 容器中使用 GPU ...

    1 年前
  • 了解 ES11:ECMAScript 2020 新特性指南

    ECMAScript 2020(通常被称为 ES11)是 JavaScript 的最新版本,于 2020 年 6 月正式发布。该版本包含了一些新特性和增强功能,为开发人员提供了更好的工具和能力,同时也...

    1 年前
  • K8S 中 Helm 安装 Nginx Ingress Controller

    前言 在 K8S 中使用 Nginx Ingress Controller 可以方便地实现负载均衡和流量转发,很多人在使用时会手动部署 Nginx Ingress Controller,但是手动部署复...

    1 年前
  • 如何在 Deno 中使用 WebRTC?

    WebRTC 是一项用于实现浏览器之间实时通信协议的开放标准。它是一个强大的工具,可以为开发者提供实时通信的核心组件。本文将介绍如何在 Deno 中使用 WebRTC 技术实现浏览器之间实时通信。

    1 年前

相关推荐

    暂无文章