- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
公司里的某负责保存用户文档的子系统有时会忽然cpu很高,过了大约5分钟后又恢复正常水平。领导协调让我帮看一下 (我心里是: 不熟悉这个子系统里面的代码,我尽力哈 😓 ) 。
其实确实是这样的,如果熟悉出问题的系统的代码,会对诊断问题起到很大的帮助,否则就需要更多的利用对底层的理解了.
打听后知道了这个子系统用.net core写的,可以运行在windows和linux docker上,且这次的cpu高的问题,他们在windows运行也可复现。于是,我让他们在windows上运行,发现cpu高的时候dump一下。(然后windbg就可以准备下地 干活了 😖 ) 。
在用windbg看了大部分threadpool worker线程的情况后,我发现大部分线程都运行到这样类似的call stack上
先大概看一下这个 PeopleManagementService.Program+c__DisplayClass2_0.b__0(PeopleManagementService.User) 在做什么,用IL反编译工具可以看到
再结合call stack,感觉上下文正在从某集合里查找东西呢?(一个题外话,上面那个 c__DisplayClass2_0.b__0 名字挺奇怪,其实这是C# compiler在build我们的C#代码到IL时帮着生成的一些code。对于目前这个,就对应我们C#程序员写出的 lambda ) 。
找东西会把cpu明显提高么?去看看 PrintUserLastEnteredTimeDetail() 在干什么吧。(其实子系统team的同事人很好,所以这次我直接找他要对应的代码得 了 👦 ) 简化代码:
看起来是在一个叫 users 的List中按条件查找东西。看看这个list的size, 用 !do 试一下:
1 0 : 027 > !DumpObj / d 0000019a8000d938 2 Name: System.Collections.Generic.List` 1 [[PeopleManagementService.User, PeopleManagementService]] 3 MethodTable: 00007ff96c313e88 4 EEClass: 00007ff96c2df530 5 Tracked Type: false 6 Size: 32 ( 0x20 ) bytes 7 File: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\ 6.0 . 14 \System.Private.CoreLib.dll 8 Fields: 9 MT Field Offset Type VT Attr Value Name 10 00007ff96c2fd618 4002099 8 System.__Canon[] 0 instance 0000019a90bc12a0 _items 11 00007ff96c2a94b0 400209a 10 System.Int32 1 instance 524288 _size 12 00007ff96c2a94b0 400209b 14 System.Int32 1 instance 524288 _version 13 00007ff96c2fd618 400209c 8 System.__Canon[] 0 static dynamic statics NYI s_emptyArray
在告知同事这个原因前,我还有意无意地查了一下那个保存big list的Dictionary,用 !gcroot
然后 !do 看一下:
1 ! do 0000019A8000D818 2 Name: System.Collections.Generic.Dictionary` 2 +Entry[[System.String, System.Private.CoreLib],[System.Collections.Generic.List` 1 [[PeopleManagementService.User, PeopleManagementService]], System.Private.CoreLib]][] 3 MethodTable: 00007ff96c322808 4 EEClass: 00007ff96c322770 5 Tracked Type: false 6 Size: 96 ( 0x60 ) bytes 7 Array: Rank 1 , Number of elements 3 , Type VALUETYPE
64位的进程运行环境,clr array的第一个item在 0000019A8000D818 + 8(mt ptr size) + 4(length field) + 4 (padding) ,所以看标红的那两个地址.
1 0 : 027 > !DumpObj / d 0000019a8000cce8 2 Name: System.String 3 MethodTable: 00007ff96c2bd708 4 EEClass: 00007ff96c299d60 5 Tracked Type: false 6 Size: 30 ( 0x1e ) bytes 7 File: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\ 6.0 . 14 \System.Private.CoreLib.dll 8 String: Male
1 0 : 027 > !DumpObj / d 0000019a8000cd08 2 Name: System.String 3 MethodTable: 00007ff96c2bd708 4 EEClass: 00007ff96c299d60 5 Tracked Type: false 6 Size: 34 ( 0x22 ) bytes 7 File: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\ 6.0 . 14 \System.Private.CoreLib.dll 8 String: Female
原来Dictionary按性别分类保存了所有的用户信息.
我把这些信息告诉同事,他第一反应是没有想到这个运行的结果。按照他的代码,他预期是按性别和用户名一起来当key,然后放到Dictionary,这样查询起来至少时间复杂度不应这么高。于是我和那个同事打开相关的生成key的代码:
1 private static string GetUserKey(Gender gender, string userName) => string .Join(userName, gender);
这么错误的使用,就相当于把user name作为separator,而后面的集合参数其实就传了一个性别,所以生成的key就总是同一个,本想做成user cache的Dictionary的数据最终退化为两个很大的lists 😓 然后多个线程一起在这两个大大的list上以O(n)的时间复杂度查找东西,cpu就高起来了…… 。
最后此篇关于公司某资料子系统定期cpu过高的诊断的文章就讲到这里了,如果你想了解更多关于公司某资料子系统定期cpu过高的诊断的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
你怎么能管理这样的事情?我尽我最大的努力将子系统设计为可重用,但只有某些特定于站点的东西必须自定义(例如 Account 实体中的字段,或 orm 注释中的 cfc="")。 我曾想过使用 SVN 并
我正在编写 native 模式应用程序(想想: link /subsystem:native )。这意味着我不能使用 kernel32.dll 中的任何内容,这(显然)在 C 运行时库中没有任何意义。
我注意到使用 emscripten,即使是相对较小的 C++ 文件也可以快速转换为相当大的 JavaScript 文件。示例: #include int main(int argc, char**
在恢复模式下运行标准 Windows 7 安装盘时,如果您打开命令行并运行自定义构建的应用程序,您将收到错误“不支持子系统”。我试过与/SUBSYSTEM:CONSOLE、WINDOWS 和 NATI
我有一个生成一些报告并在 GUI 中显示相同内容的 MFC 应用程序。当使用某些命令行参数传递时,我需要将它作为控制台应用程序运行。在控制台模式下,它将在标准输出/错误中生成报告/错误,我应该能够将其
本文讲解 pinctrl 子系统和 gpio 子系统的 API,以及使用示例。 传统的配置 pin 的方式就是直接操作相应的寄存器,但是这种配置方式比较繁琐、而且容易出问题(比如 pin 功能
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 8 年前。
Windows Vista Enterprise 和 Ultimate 的要点功能之一是 Windows 的 Unix 子系统,它允许您编写 posix... 东西?不管怎样,我不喜欢谈论它……有人使
我在 Windows 10 上的 WSL 中使用 Ubuntu,并且我在 WSL 中安装了 git 并定期使用它。我有一个非常烦人的问题,我尝试缓存我的 github 凭据,因此我不必在提交时不断输入
我正在使用旧的 bcc32 (borland 5.5)(我知道这很旧编译器但不要告诉我我不应该使用它) 我可以使用控制台或 Windows 子系统进行编译。 我不想用 windows 子系统编译,我想
设置: 榛子:3.12.3 Spring 启动:2.1.6 Java:1.8 参数:-XX:+UseG1GC Xms7g -Xmx7g 这些正在 Docker 中运行:openjdk:8 它们在专用
我曾经在 Windows 10 的 Linux 子系统上通过 bash 控制台通过 ssh 连接到我的服务器。 我重新安装了 Windows,并将 id_rsa、id_rsa.pub 和 known_
我目前在我的 C 代码中使用 inotify() 系统来监视文件系统中某些目录的事件。 现在,使用这些东西之一的过程如下。你取一个整数(比如 event_notifier),使用 inotify_in
安装 WSL 1. 开启WSL 必须启用“适用于 Linux 的 Windows 子系统”可选功能并重启,然后才能在 Windows 上运行 Linux 发行版。 以管理员运行Powershell(开
我正在学习如何使用 https://intermezzos.github.io 构建基本的操作系统内核 我已经创建了我的 .iso文件,我正在运行 qemu-system-x86_64 -cdrom
不久前我使用 crontab -e 设置了一些 cronjobs .我的 crontab 包括以下行: * * * * * /usr/bin/touch /home/blah/MADEBYCRON 我
我已经安装了 visual studio 2008 Professional Edition,但我无法在其中一个 visual C++ 项目中设置/SUBSYSTEM:POSIX 选项。我还从 SUA
基本上,我需要一个程序来将 Windows .exe 从控制台对应项中排序。 文件扫描器: SortExe(file exe) { if (IsPeWindows(exe)) {
我有一个 python 脚本,我想在计算机的剪贴板中放置一个字符串。我在 Linux、Mac 和以前使用 cygwin 在 Windows 中工作。我不得不修改一行代码以使其在各自的系统中工作。我无法
最近发布了 Windows 10 周年更新的新更新,包括 Linux 子系统 based on Ubuntu 14.04而现在我希望我所有的工作环境都在这个 Linux 子系统中。 我尝试按照官方网站
我是一名优秀的程序员,十分优秀!