当前位置: 首页 > news >正文

宠物网站建设策划方案做网站想注册商标是哪一类

宠物网站建设策划方案,做网站想注册商标是哪一类,商城网站制作的教程,门户网站建设和检务公开情况自查报告目录 1、WebRTC简介 2、问题现象描述 3、将Windbg附加到目标进程上分析 3.1、Windbg没有附加到主程序进程上#xff0c;没有感知到异常或中断 3.2、Windbg感知到了中断#xff0c;中断在DebugBreak函数调用上 3.3、32位进程用户态虚拟地址和内核态虚拟地址的划分 …目录 1、WebRTC简介 2、问题现象描述 3、将Windbg附加到目标进程上分析 3.1、Windbg没有附加到主程序进程上没有感知到异常或中断 3.2、Windbg感知到了中断中断在DebugBreak函数调用上     3.3、32位进程用户态虚拟地址和内核态虚拟地址的划分 4、用户态内存不足问题分析虚拟 4.1、判断是内存不足导致了malloc申请内存失败 4.2、为啥会中断在DebugBreak函数调用处呢 5、占用程序进程的虚拟内存的因素有哪些     5.1、二进制文件 5.2、线程的栈空间 5.3、程序中申请的堆内存 6、当前用户态虚拟内存占用高的解决办法 6.1、修改WebRTC编译选项减少内存占用 6.2、将程序做成64位的 6.3、使用Visual Studio的链接选项将用户态虚拟内存从2GB扩充到3GB 6.4、使用多进程模式 7、最后 VC常用功能开发汇总专栏文章列表欢迎订阅持续更新...https://blog.csdn.net/chenlycly/article/details/124272585C软件异常排查从入门到精通系列教程专栏文章列表欢迎订阅持续更新...https://blog.csdn.net/chenlycly/article/details/125529931C软件分析工具从入门到精通案例集锦专栏文章正在更新中...https://blog.csdn.net/chenlycly/article/details/131405795C/C基础与进阶专栏文章持续更新中...https://blog.csdn.net/chenlycly/category_11931267.html开源组件及数据库技术专栏文章持续更新中...https://blog.csdn.net/chenlycly/category_12458859.html       本文分享一下最近遇到的一个因虚拟内存不足导致程序发生闪退的问题排查案例案例具有一定的代表性希望能给大家提供一定的借鉴或参考。 1、WebRTC简介 本案例中的软件是基于开源库WebRTC构建的发生的软件问题也是与WebRTC有关的所以先给大家简要地介绍一下WebRTC相关的内容。 WebRTCWeb Real-Time Communication是一个由Google发起的实时音视频通讯C开源库其提供了音视频采集、编码、网络传输解码显示等一整套音视频解决方案我们可以通过该开源库快速地构建出一个音视频通讯应用。 一个实时音视频应用软件一般都会包括这样几个环节音视频采集、音视频编码压缩、前后处理美颜、滤镜、回声消除、噪声抑制等、网络传输、解码渲染音视频播放等。其中每一个细分环节还有更细分的技术模块。 虽然其名为WebRTC但是实际上它不光支持Web之间的音视频通讯还支持Windows、Android以及iOS等移动平台。WebRTC底层是用C/C开发的具有良好的跨平台性能。 WebRTC因为其较好的音视频效果及良好的网络适应性目前已被广泛的应用到视频会议、实时音视频直播等领域中。在视频会议领域腾讯会议、华为WeLink、字节飞书、阿里钉钉、小鱼易连、厦门亿联等国产厂商均提供了基于WebRTC方案的视频会议。 大家熟知的音视频专业服务商声网Agora更是基于开源WebRTC库提供了社交直播、教育、游戏电竞、IoT、AR/VR、金融、保险、医疗、企业协作等多个行业的音视频互动解决方案。使用声网服务的企业包括小米、陌陌、斗鱼、哔哩哔哩、新东方、小红书、HTC VIVE 、The Meet Group、Bunch、Yalla等遍布全球的巨头、独角兽及创业企业。除了头部公司声网之外也陆续有多家公司基于开源的WebRTC开发出了多个音视频应用提供了多个领域的音视频通信解决方案。 2、问题现象描述 基于WebRTC的会议软件在加入会议后会时不时发生闪退虽然不是必现的但已经有好几个用户反馈了并且在某技术支持同事的电脑上也出现了频繁闪退的问题。程序闪退时程序中安装的异常捕获模块没有感知到所以没有生成dump文件。 虽然我们在程序中安装了异常捕获模块但并不能捕获所有的软件异常或崩溃只能捕获大部分的异常所以程序发生异常时没有感知到也实属正常。 3、将Windbg附加到目标进程上分析 对于这类没有生成dump文件的场景就需要使用Windbg进行动态调试了即将Windbg附加到目标进程上和目标进程一起跑。于是让这个技术支持同事每次运行软件时都手动将Windbg附加到进程上和进程一起跑这样一旦程序发生异常Windbg就会感知到就会中断下来这样就能看到出问题时的函数调用堆栈就可以分析了。 3.1、Windbg没有附加到主程序进程上没有感知到异常或中断 但这位同事复现问题后Windbg并没有中断下来即Windbg没有感知到按讲是不应该的一旦程序发生异常正在调试的Windbg会第一时间感知到并中断下来。后来发现他是在Windbg中打开桌面快捷方式文件去启动软件的而桌面快捷方式指向的是个引导启动的程序不是主程序该程序做一些初始校验的操作校验通过后会自动将主程序启动起来。这样Windbg附加到的是引导程序的进程上并没有附加到主程序进程上。 就像QQ的桌面快捷方式指向的是QQ安装目录下的QQScLauncher.exe 该程序会做一些启动主程序QQ.exe前的一些检查然后会将主程序QQ.exe启动起来。 在我们这个问题中可以先将主程序启动起来然后再将Widnbg附加到主程序进程上就可以了。也可以通过Windbg将主程序启动起来需要到安装目录中找到主程序的exe文件打开该文件不能通过桌面快捷方式去启动。 3.2、Windbg感知到了中断中断在DebugBreak函数调用上     后来同事每次运行程序时都将Windbg附加到程序进程上复现了问题正在调试的Windbg中断了下来发现中断在DebugBreak接口调用处如下所示 输入kn命令查看此时的函数调用堆栈  正是DebugBreak接口就是让正在调试的进程中断下来的。使用kn命令查看此时的函数调用堆栈发现是WebRTC库中在调用malloc动态申请内存时返回了NULL然后WebRTC库内部认为是异常情况可能是认为内存申请不到后相关的业务都没法执行了程序继续运行就没有意义了于是直接调用abort接口将进程终止了。 这就能说明为啥程序闪退时异常捕获模块没有感知到异常因为malloc申请内存失败返回NULL并没有产生C异常程序闪退是因为WebRTC内部调用abort接口强行将进程终止掉了。 至于为啥会出现malloc申请内存失败的问题呢估计是用户态的虚拟内存不够用了我们的程序是32位的系统会给程序进程分配4GB的虚拟内存其中2GB是用户态的虚拟内存我们的程序用户态的内存快到达上限了没有空闲内存可用了所以malloc申请内存失败了返回了NULL。 关于如何使用Windbg进行动态调试使用Windbg进行动态调试的完整步骤可以参见我之前写的文章 使用Windbg动态调试目标进程的一般步骤及要点详解https://blog.csdn.net/chenlycly/article/details/131029795 3.3、32位进程用户态虚拟地址和内核态虚拟地址的划分 对于32为程序是按32位进行内存寻址的所以给32位程序进程分配了4GB的虚拟内存程序中所使用的内存均是从这4GB的虚拟内存上划拨的比如全局变量占用的内存、线程栈内存、程序申请的堆内存、二进制文件占用的代码段内存等。 32位进程的这4GB虚拟内存在Windows平台上默认情况下2GB是用户态虚拟内存2GB是内核态虚拟内存在Linux平台上默认情况下3GB是用户态虚拟内存1GB是内核态虚拟内存。 此外用户态的代码只能访问用户态的内存地址是禁止访问内核态内存地址的内核态的代码只能访问内核态的内存地址是禁止访问用户态内存地址的。关于32位进程和64位进程的虚拟内存地址划分可以参见《Windows核心编程》一书中的截图 我们以前在排查软件异常崩溃时经常遇到崩溃的那条汇编代码位于用户态代码中中访问了内核态的内存地址可能是访问了未初始化的变量内存也可能是访问了因内存越界被篡改的内存用户态代码是禁止访问内核态内存地址的强行访问会触发内存访问违例引发程序崩溃。 C软件异常基本内存有关关于引发C程序内存错误的常见原因可以参见我之前的文章 引发C程序内存错误的常见原因分析与总结https://blog.csdn.net/chenlycly/article/details/128599525 4、用户态内存不足问题分析虚拟 4.1、判断是内存不足导致了malloc申请内存失败 复现问题时Windbg正好中断下来软件进程暂停下来正好此时使用Process Explorer查看我们软件进程的虚拟内存确实已经用到1.8GB左右了快接近2GB的上限了其实离2GB的上限还有200MB的空余但可能因为内存碎片的存在都是一小块一小块分散的小内存块而程序中要申请的是一段连续的内存块找不到指定大小的连续内存块就会出现内存分配失败了。 如果在正在调试的Windbg中使用.dump命令手动导出dump文件我们也可以事后通过dump文件的大小去初步估计出问题时进程占用的虚拟内存大小。在Windbg中导出的dump文件属于全dump文件将当时进程的内存信息都保存了下来dump文件的大小接近当时进程的虚拟内存大小可能会略小一点点。 内存碎片的概念之前听说过在这种场景下才感受到内存碎片的危害有人说可以使用内存池内存池可以减少内存碎片的出现但实际上程序业务需要占用更多的内存减少内存碎片也解决不了问题。 4.2、为啥会中断在DebugBreak函数调用处呢 复现问题时为啥会中断在DebugBreak函数调用处呢查看了函数调用堆栈中函数在WebRTC中的源码malloc返回失败的代码如下所示 1申请内存的malloc返回NULL 2malloc返回NULL会执行到RTC_CHECK宏中的rtc_FatalMessage接口  3紧接着调用到FatalLog接口  4 FatalLog接口的实现如下 我们在FatalLog接口的结尾处我们看到了DebugBreak系统API接口的调用然后紧接着调用C函数abort。 Windows API接口DebugBreak的作用就是让正在调试的调试器中断下来目的是让调试器感知到当前的事件所以Windbg中断在DebugBreak函数的调用处。此外在调用DebugBreak接口后会紧接着调用abort接口将当前进程终止掉应该是WebRTC内部认为内存申请失败了业务没法正常展开了程序没法正常运行没有继续存活下去的意义了所以强行将程序进程终止了。 调用C函数malloc申请内存申请失败时malloc会返回NULL不会抛出异常如果使用new去申请申请失败时默认会抛出bad_alloc异常如果程序中没有处理这个异常则会导致程序发生异常崩溃。当然我们可以在new时使用nothrow不让其抛出异常返回NULL示例代码如下 #include iostreamint main(){char *p NULL;int i 0;do{p new(std::nothrow) char[10*1024*1024]; // 每次申请10MBi;Sleep(5);}while(p);if(NULL p){std::cout 分配了 (i-1)*10 M内存 //分配了 1890 Mn内存第 1891 次内存分配失败 第 i 次内存分配失败;}return 0; } 另外abort的调用也会让正在调试的Windbg中断下来我们来看看abort函数的内部实现 /*** *void abort() - abort the current program by raising SIGABRT * *Purpose: * print out an abort message and raise the SIGABRT signal. If the user * hasnt defined an abort handler routine, terminate the program * with exit status of 3 without cleaning up. * * Multi-thread version does not raise SIGABRT -- this isnt supported * under multi-thread. *******************************************************************************/ void __cdecl abort (void) {_PHNDLR sigabrt_act SIG_DFL;#ifdef _DEBUGif (__abort_behavior _WRITE_ABORT_MSG){/* write the abort message */_NMSG_WRITE(_RT_ABORT);} #endif /* _DEBUG *//* Check if the user installed a handler for SIGABRT.* We need to read the user handler atomically in the case* another thread is aborting while we change the signal* handler.*/sigabrt_act __get_sigabrt();if (sigabrt_act ! SIG_DFL){raise(SIGABRT);}/* If there is no user handler for SIGABRT or if the user* handler returns, then exit from the program anyway*/if (__abort_behavior _CALL_REPORTFAULT){_call_reportfault(_CRT_DEBUGGER_ABORT, STATUS_FATAL_APP_EXIT, EXCEPTION_NONCONTINUABLE);}/* If we dont want to call ReportFault, then we call _exit(3), which is the* same as invoking the default handler for SIGABRT*/_exit(3); } 上述代码中先调用了raise(SIGABRT)该函数是触发一个SIGABRT信号终止异常如果当前正在调试状态会让调试器中断下来。接下来调用C函数_exit退出当前进程。  关于调用abort强制终止程序导致程序闪退的案例还可以查看我之前的文章 C程序中执行abort等操作导致没有生成dump文件的问题案例分析https://blog.csdn.net/chenlycly/article/details/129003869 5、占用程序进程的虚拟内存的因素有哪些     占用进程的虚拟内存空间的因素有很多这里大概地罗列几个大家可以简单地了解一下。我们可以从程序的五大内存分区的角度去看程序的五大内存分区如下 5.1、二进制文件 主程序及主程序依赖的二进制库文件都需要加载到进程空间中都占用一定的虚拟内存。exe主程序依赖底层的多个业务库和系统dll库比如业务库有组件dll库、协议dll库、网络dll库、开源库等可能会依赖上百个dll库。这些dll库在主程序启动时会加载到程序进程的进程空间中会占用进程的虚拟内存空间属于代码段的虚拟内存。 如果能减少dll库的依赖减小依赖的dll库文件的大小可以减少程序对虚拟内存的占用。特别对于一些大型的开源库一方面要减少程序安装包的大小另一方面减少二进制文件对虚拟内存的占用需要进行一些裁剪开源库中也提供了一些宏开关和编译选项。比如google开源的嵌入式浏览器框架库libcef默认是比较大的编译后的dll库要占到好几十MB可以对该库进行裁剪。有时为了进行深度的裁剪和优化甚至会去直接修改开源代码。 5.2、线程的栈空间 程序中创建了多个线程多个模块都创建了线程每个线程都要分配对应的栈空间线程越多占用的栈空间越多这是栈空间也是从进程的虚拟内存上划拨的。但对于应用程序开多个线程去并行处理任务也是必不可少的。 对于线程占用的栈空间大小Windows下每个线程默认的栈空间大小是1MBLinux下每个线程的默认的栈空间是8MB。 5.3、程序中申请的堆内存 C程序中使用的大部分内存都是堆内存堆内存占总虚拟内存的大部分。堆内存是通过使用new或者调用malloc等函数申请的。 在Windows平台上动态申请内存的方式有多种比如使用new要用delete去释放比如使用malloc要用free去释放再比如调用系统API函数HeapCreate或者HeapAlloc要用HeapFree去释放还有可以调用API函数VirtualAlloc要用VirtualFree去释放还有其他的API函数。 要尽量节约内存按需分配使用的buffer大小可能会动态变化频繁动态地去申请和释放内存可能会产生很多内存碎片。这也是上来就申请固定长度的buffer的好处可以减小生成内存碎片。使用内存池可以减少内存碎片但对于本问题确实需要使用很多虚拟内存使用内存池减少内存碎片作用也不是很大。 6、当前用户态虚拟内存占用高的解决办法 WebRTC开源库比较大会消耗很多的内存如何解决WebRTC占用大量虚拟内存的问题有如下的方法。 6.1、修改WebRTC编译选项减少内存占用 可以尝试修改WebRTC编译选项对其进行裁剪缩编释放出一些占用内存的代码但这种做法降低内存的效果有限因为WebRTC作为大型库本来就需要占用大量的内存资源。 6.2、将程序做成64位的 可以将主程序做成64位的64位程序的用户态虚拟内存非常大可以“肆无忌惮”的使用。但占用的虚拟内存过大在代码执行过程中虚拟内存要切换到物理内存上会来回频繁地切换也会影响程序的执行效率。此外物理内存较小也会影响虚拟内存到物理内存的切换也会显著降低程序的运行速度。 6.2.1、我们的程序为了兼容32位系统需要做成32位的 我们的程序之所以还是32位的是因为我们需要兼容32位系统。有些人说为啥不直接将主程序做成x6464位程序的呢因为我们的程序还要兼容32位的系统虽然现在普遍使用的Win10和Win11都是64位的但还有少部分客户在使用32位的Win7系统什么样的客户都有不排除有使用32位系统的可能。 64位程序是没法在32位系统上运行的但32位程序可以在64位系统上运行这是操作系统去做兼容的。 6.2.2、关于32位程序和64位程序的说明 32位exe或dll是不能和64位exe或exe文件混用的系统是严格区分二进制文件位数的32位exe或dll文件只能使用依赖32位exe或dll文件64位exe或dll文件只能使用依赖64位的exe或dll文件。比如32位的exe主程序如果使用64位dll库则启动时会报错。 对于Windows系统库64位系统的系统库都有两个版本的分别是32位系统库和64位系统库。32位的系统库则存放在C:\Windows\SysWOW64目录中注意WOW64不是64位系统库目录WOW64是32位程序运行在64位系统上的意思64位系统库存放在C:\Windows\System32目录中 所以32位程序依赖的32位系统库都在C:\Windows\SysWOW64目录中。这个SysWOW64和system32目录很容易混淆前几天还有个同事问我这两个目录对应关系到底是啥他之前一度以为system32目录下的是32位系统库SysWOW64目录下的是64位系统库事实却正好相反。 当32位程序在64位Windows上运行时会有个重定向问题可以查看我之前的文章 关于32位程序在64位系统下运行中需要注意的重定向问题有图有真相https://blog.csdn.net/chenlycly/article/details/53119127Win7用户帐户控制数据重定向https://blog.csdn.net/chenlycly/article/details/53408212 6.3、使用Visual Studio的链接选项将用户态虚拟内存从2GB扩充到3GB 可以在Visual Studio链接选项中打开扩大用户态虚拟内存的选项/L largeAddressAware如下所示 这样可以将用户态虚拟内存扩到3GB这样可以有效缓解内存不够用的问题。 32进程只有4GB的虚拟内存如果将用户态虚拟内存由2GB扩到3GB内核态的虚拟内存应该会被压缩到1GB这样会不会导致内核态的代码执行比较慢导致程序的运行性能下降呢可能运行性能会有一定的损失但既然系统运行这种扩充用户态虚拟内存的方式应该影响不会很大。 6.4、使用多进程模式 但上述方法在使用WebRTC开源库时可能有问题如果要解更多路数的视频会占用更多的内存。可以考虑将WebRTC封装成进程使用多进程的模式主进程与WebRTC进程使用RPC方式进行接口的调用。像Chrome那样搞多个进程不同的进程处理不同的事务一个进程崩溃了不会影响到主进程将崩溃的进程重新启动。但是多个进程之间需要通信需要协同控制控制不好也容易出问题。进程之间如何高效地的传递数据也是个问题这都需要人力和技术去支撑。但多进程模式将是最终且最稳妥的解决方案。 7、最后 针对我们遇到的上述问题目前的做法是一边优化内存占用一边使用扩大用户态虚拟内存的做法同步进行。
http://www.zqtcl.cn/news/681885/

相关文章:

  • 网站版面布局结构网站建设公司公司
  • 给新公司建网站中国互联网企业排名前十名
  • 中国建设银行网站会员用户名网站建设应列入啥费用
  • 网站上面的水印怎么做的广东网站建设公
  • 爱站网关键词长尾挖掘工具wordpress文章外链
  • 做视频剪辑接私活的网站网站商城系统设计
  • thinkphp5做网站做网站需要准备资料
  • 门户网站平台建设方案建e室内设计网cad
  • 西安网站建设收费标准第五次全国经济普查
  • 成品网站货源1688免费襄阳公司网站建设
  • 2020国内十大小说网站排名365网站
  • 潍坊做网站的网络公司网页设计入门教材pdf
  • 影视公司网站建设wordpress 500ms
  • 旅游网站建设公司crm客户管理系统模板
  • 哪个网站有免费的模板阿里云上如何用iis做网站
  • 中山优化网站门户网站建设jz190
  • 湖州服装网站建设网站备案和域名备案区别
  • 网站开发好学嘛网络安全工程师年薪
  • 17网站一起做网店睡衣网线制作流程
  • 广告网站设计公司好吗网站页面设计主要包括
  • 网站的做重庆市建设工程造价信息表
  • 建网站跟建网店的区别怎样营销建设网站
  • 医院做网站的风格乐清网站建设哪家好
  • 手机商城网站方案如何自己搭建微信小程序
  • 做影视免费网站违法吗青岛快速排名优化
  • 网站建设在电子商务中的作用的看法360地图怎么添加商户
  • 网站域名备案与不备案的区别wordpress 注册审核
  • 大学生做企业网站网页设计免费模板情侣
  • 商城网站建设教程网站开发支付宝
  • 广安网站设计快递加盟代理