内存不足引发C++程序闪退崩溃问题的分析与总结
目录
1、内存不足一般出现在32位程序中
2、内存不足时会导致malloc或new申请内存失败
2.1、malloc申请内存失败,返回NULL
2.2、new申请内存失败,抛出异常
3、内存不足项目实战案例中相关细节与要点说明
3.1、内存不足导致malloc申请内存失败,导致程序闪退
3.1.1、内存不足导致程序闪退的原因
3.1.2、abort强制终止进程导致程序闪退时,不会生成dump文件
3.2、内存不足导致new申请内存时抛出异常,引发程序崩溃
4、引发内存不足的两个原因
4.1、32位程序默认的用户态虚拟内存只有2GB,程序模块较多,可能占用的内存接近2GB了
4.2、程序中有内存泄漏,且内存泄漏的代码在不断的执行,导致程序占用内存越来越多
5、解决内存不够用的办法
6、最后
C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/125529931C/C++实战进阶(已更新到460多篇,持续更新中...)
https://blog.csdn.net/chenlycly/article/details/140824370VC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)
https://blog.csdn.net/chenlycly/article/details/124272585Windows C++ 软件开发从入门到精通(专栏文章,持续更新中...)
https://blog.csdn.net/chenlycly/category_12695902.htmlC++软件分析工具从入门到精通案例集锦(专栏文章,持续更新中...)
https://blog.csdn.net/chenlycly/article/details/131405795开源组件及数据库技术(专栏文章,持续更新中...)
https://blog.csdn.net/chenlycly/category_12458859.html网络编程与网络问题分享(专栏文章,持续更新中...)
https://blog.csdn.net/chenlycly/category_2276111.html 最近在项目中遇到几个因为内存不足引发程序闪退或崩溃的问题,比较有代表性,所以本文在此总结一下内存不足的相关问题场景以及内存不足引发程序异常的具体原因,供大家借鉴或参考。
1、内存不足一般出现在32位程序中
C++程序按位数可以分为32位和64位程序。对于64位程序,内存地址按64位寻址,系统会给64位程序分配0-0xFFFFFFFFFFFFFFFF这个范围的虚拟地址。而对于32位程序,内存地址按32位寻址,系统会给32位程序分配0-0xFFFFFFFF这个范围的虚拟内存,即4GB虚拟内存:
所以系统给64位程序分配的虚拟内存空间要比32位程序大的多,几乎是“用之不竭”的,所以内存不足基本是出现在32位程序中。
对于32位程序,系统在其启动时分配4GB的虚拟内存,默认情况下,用户态虚拟内存和内核态虚拟内存各占2GB,而C++程序基本都运行在用户态,用户态虚拟内存只有2GB,当占用内存的模块很多或者有内存泄漏时,很容易接近这个2GB的上限,从而出现内存不足的问题,进而导致程序发生闪退或崩溃。
虽然系统给64程序分配的虚拟内存非常大,但在有内存泄漏的情况下也可能会出现内存不足的问题。比如程序一直在持续的运行(程序不关闭),且在持续的发生内存泄漏,则再大的虚拟内存空间也有用尽的那一刻。
2、内存不足时会导致malloc或new申请内存失败
C++程序在运行过程中主要使用全局内存、栈内存和堆内存,而全局内存是在程序启动时(进入main函数之前)就分配好了,栈内存和堆内存则是在程序运行过程中分配或申请的。栈内存则是和线程相关的,在创建线程时系统会给线程分配指定大小的栈内存,线程中调用的函数中的局部变量使用的都是栈内存。
在Windows系统中,系统默认给线程分配1MB的栈空间;在Linux系统中,系统默认给线程分配8MB的栈空间。线程中调用的函数会使用线程的栈空间,如果当前线程中调用的函数占用的总的栈空间超过系统分配给系统的上限,则会导致Stack oveflow线程栈溢出的异常,导致程序崩溃。关于引发Stack oveflow线程栈溢出的常见原因及详细说明,可以查看我的文章:
通过Stack Overflow线程栈溢出的问题实例,详解C++程序线程栈溢出的诸多细节
https://blog.csdn.net/chenlycly/article/details/140908516
线程占用的栈空间相对不多,C++程序中使用更多的还是堆内存,所以我们此处主要讨论内存不足对申请堆内存的影响。C++程序中主要使用C函数malloc或者new操作符去申请堆内存,当内存不足时使用malloc和new的反应是有所不同的:
1)malloc申请内存失败时会返回NULL;
2)new申请内存失败时会抛出异常,导致程序发生崩溃。
在Windows C++程序中,除了使用new去申请堆内存,还可以调用Windows系统API函数HeapAlloc从堆上分配内存(要用HeapFree去释放),还可能调用API函数VirtualAlloc或VirtualAllocEx从虚拟内存上分配内存(要用VirtualFree或VirtualFreeEx去释放),还可能调用其他的API函数。本文主要讨论使用new的场景。
2.1、malloc申请内存失败,返回NULL
malloc申请内存失败时,会返回NULL,通过这个NULL返回值就可以判断内存申请失败了。
malloc申请内存失败,可能会引发程序发生闪退(注意内存申请失败本身不会导致程序闪退崩溃)。之前我们在项目中就遇到过,我们的程序使用了开源的WebRTC库,当时程序中有内存泄漏,内存不够用了,导致WebRTC开源库内部代码在调用malloc申请内存时失败了,malloc返回NULL,WebRTC内部判断malloc返回NULL,认为这个是fatal致命的(因为申请不到内存,业务没法正常的展开,WebRTC内部认为这是致命的),直接调用abort强行将当前进程终止了,相关代码如下:
RTC_CHECK宏会校验malloc的返回值,如下:
如果malloc返回的地址为空,则会调用rtc_FatalMessage接口:
rtc_FatalMessage接口内部会调用FatalLog:
FatalLog接口中会在末尾处先是调用DebugBreak接口,如果当前程序正在调试,则DebugBreak会让调试器中断下来(从DebugBreak函数名就能看出这个函数的作用),目的是让正在调试的用户感知到!然后紧接着会调用abort接口,将当前进程强制终止掉!
其实abort接口内部也会让正在调试的调试器中断下来,abort的内部实现代码如下所示:
/***
*void abort() - abort the current program by raising SIGABRT
*
*Purpose:
* print out an abort message and raise the SIGABRT signal. If the user
* hasn't defined an abort handler routine, terminate the program
* with exit status of 3 without cleaning up.
*
* Multi-thread version does not raise SIGABRT -- this isn't 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 don't want to call ReportFault, then we call _exit(3), which is the* same as invoking the default handler for SIGABRT*/_exit(3);
}
从上述代码可以看出,abort内部调用了raise(SIGABRT),该函数是触发一个SIGABRT信号终止异常,如果当前正在调试状态,会让调试器中断下来。最后调用了C函数_exit退出当前进程。
注意,上述问题中并没有产生C++异常,是调用abort强行终止进程的,程序直接闪退消失了,给人感觉是程序崩溃了,实际上并不是崩溃!这个项目问题案例,我之前专门写了文章,可以去查看文章:
WebRTC开源库内部调用abort函数引发C++程序发生闪退问题的详细排查https://blog.csdn.net/chenlycly/article/details/129460580 对于这种调用abort强行终止进程的问题,还有一个细节值得注意一下。如果程序中安装了异常捕获,此种场景下是不会生成dump文件的。因为当前是WebRTC开源库内部检测到malloc返回NULL,直接调用abort,程序并没有发生C++上的异常,所以异常捕获是感知不到的(发生C++上的异常,异常捕获模块才能感知到),虽然给人一种程序发生崩溃闪退的感觉,但不会生成dump文件的。
在这里,给大家重点推荐一下我的几个热门畅销专栏,欢迎订阅:(博客主页还有其他专栏,可以去查看)
专栏1:(该精品技术专栏的订阅量已达到560多个,专栏中包含大量项目实战分析案例,有很强的实战参考价值,广受好评!专栏文章持续更新中,预计更新到200篇以上!欢迎订阅!)
C++软件调试与异常排查从入门到精通系列文章汇总https://blog.csdn.net/chenlycly/article/details/125529931
本专栏根据多年C++软件异常排查的项目实践,系统地总结了引发C++软件异常的常见原因以及排查C++软件异常的常用思路与方法,详细讲述了C++软件的调试方法与手段,以图文并茂的方式给出具体的项目问题实战分析实例(很有实战参考价值),带领大家逐步掌握C++软件调试与异常排查的相关技术,适合基础进阶和想做技术提升的相关C++开发人员!
考察一个开发人员的水平,一是看其编码及设计能力,二是要看其软件调试能力!所以软件调试能力(排查软件异常的能力)很重要,必须重视起来!能解决一般人解决不了的问题,既能提升个人能力及价值,也能体现对团队及公司的贡献!
专栏中的文章都是通过项目实战总结出来的,包含大量项目问题实战分析案例,有很强的实战参考价值!专栏文章还在持续更新中,预计文章篇数能更新到200篇以上!
专栏2:(本专栏涵盖了C++多方面的内容,是当前重点打造的专栏,订阅量已达210多个,专栏文章已经更新到470多篇,持续更新中...)
C/C++实战进阶(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/category_11931267.html
以多年的开发实战为基础,总结并讲解一些的C/C++基础与项目实战进阶内容,以图文并茂的方式对相关知识点进行详细地展开与阐述!专栏涉及了C/C++领域多个方面的内容,包括C++基础及编程要点(模版泛型编程、STL容器及算法函数的使用等)、数据结构与算法、C++11及以上新特性(不仅看开源代码会用到,日常编码中也会用到部分新特性,面试时也会涉及到)、常用C++开源库的介绍与使用、代码分享(调用系统API、使用开源库)、常用编程技术(动态库、多线程、多进程、数据库及网络编程等)、软件UI编程(Win32/duilib/QT/MFC)、C++软件调试技术(排查软件异常的手段与方法、分析C++软件异常的基础知识、常用软件分析工具使用、实战问题分析案例等)、设计模式、网络基础知识与网络问题分析进阶内容等。
专栏3:
C++常用软件分析工具从入门到精通案例集锦汇总(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/article/details/131405795
常用的C++软件辅助分析工具有SPY++、PE工具、Dependency Walker、GDIView、Process Explorer、Process Monitor、API Monitor、Clumsy、Windbg、IDA Pro等,本专栏详细介绍如何使用这些工具去巧妙地分析和解决日常工作中遇到的问题,很有实战参考价值!
专栏4:
VC++常用功能开发汇总(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/article/details/124272585
将10多年C++开发实践中常用的功能,以高质量的代码展现出来。这些常用的高质量规范代码,可以直接拿到项目中使用,能有效地解决软件开发过程中遇到的问题。
专栏5:
C++ 软件开发从入门到精通(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/category_12695902.html
根据多年C++软件开发实践,详细地总结了C/C++软件开发相关技术实现细节,分享了大量的实战案例,很有实战参考价值。
2.2、new申请内存失败,抛出异常
当程序内存不足时,使用new去动态申请内存失败,默认情况下会抛出bad_alloc内存申请失败的异常。这种场景是产生了异常,如果程序中安装了异常捕获模块,且异常捕获模块感知到了,会生成dump文件的。比如我们有次遇到因为内存泄漏导致内存不足导致new抛出了异常,用Windbg打开dump文件,在函数调用堆栈中看到了程序中抛出了bad_alloc异常,如下所示:
从堆栈上可以看出,抛出bad_alloc异常的代码就是new那句代码抛出的是std::bad_alloc异常,就是我们讲的bad_alloc异常,导致程序发生崩溃闪退(代码中没有对这个bad_alloc异常进行处理)。
如果dump文件中显示new时抛出了bad_alloc异常,可能是内存不足导致的,可以怀疑程序中可能存在内存泄漏,然后使用工具观察程序运行过程中的内存变化,去确定是否真的是内存泄漏导致的!
这里还有一个细节,new失败抛出bad_alloc异常,不一定是内存不足导致的。也可能是程序中有堆内存越界,导致堆内存被破坏引发的。堆内存被破坏,会导致程序导出胡乱的崩溃,一会再new的地方,一会在delete的地方。堆内存被破坏的异常,是最难查的一类异常!
对于new失败时抛出bad_alloc异常导致程序崩溃,我们可以让new不要抛出异常,而是像malloc一样在申请内存失败时返回空指针,使用std::nothrow指定new不要抛出异常,如下:
#include <iostream>int 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;
}
此外,还可以使用try...catch来捕获异常:(因为异常被捕获处理了,程序也就不会再崩溃了)
#include <iostream>
using namespace std;int main(){char *p;int i = 0;try{do{p = new char[10*1024*1024];i++;Sleep(5);}while(p);}catch(const std::exception& e){std::cout << e.what() << "\n"<< "分配了" << i*10 << "M" << std::endl;}return 0;
}
虽然上面两种做法,都能让程序不再崩溃,但程序进程内存不足,业务已经没法正常展开和执行了,让程序还活着,意义也不大了。
3、内存不足项目实战案例中相关细节与要点说明
最近遇到的两个问题案例都是内存不足导致的,一个是程序占用的虚拟内存接近进程的用户态虚拟内存上限导致的,一个是程序中发生了内存泄漏引发的。这两个案例中,一个是内存不足导致了WebRTC内部malloc申请内存失败导致程序发生闪退,一个是内存不足导致了new内存时抛出了异常引发了程序崩溃。下面讲一下这两个案例涉及的细节和要点。
3.1、内存不足导致malloc申请内存失败,导致程序闪退
3.1.1、内存不足导致程序闪退的原因
我们32位程序占用了大量的虚拟内存,可能快接近程序的2GB用户态虚拟内存的上限,从而导致WebRTC库内部使用malloc申请内存时出现失败的问题!WebRTC内部可能认为malloc申请内存失败是Fatal致命的,因为相关业务无法正常展开了。然后会直接调用abort接口强行将当前进程终止掉,这样程序就闪退了。具体的代码及逻辑说明已经在上面的2.1节中详细讲述了,这里就不再展开了。
3.1.2、abort强制终止进程导致程序闪退时,不会生成dump文件
调用abort强行终止进程,程序闪退,给人一种程序发生崩溃的感觉,其实程序中并没有产生C++异常,并没有产生崩溃,所以程序中安装的异常捕获模块没有感知到(只有发生异常才会感知到),所以就没有生成dump文件。所以,项目中如果遇到程序闪退时没有产生dump文件,可能是调用abort函数强行终止进程引起的。
有时我们会尝试到系统的应用程序日志中查找程序崩溃的日志,因为日志中可能会记录程序AppCrash的记录,记录中可能会有dump文件的信息(包括dump文件的路径)。系统在感知到程序异常崩溃时,可能会自动生成包含异常上下文的dump文件。之前在项目中遇到的崩溃,到应用程序日志中查看到dump文件的信息。对于那些
所以,当程序发生闪退且没有生成dump文件时,可能是内存不足导致内存申请失败,程序中调用了abort强行终止进程导致的。对于这类问题,如果好复现,可以将Windbg附加到进程上进行动态调试,abort的调用会让Windbg中断下来,然后去查看此刻的函数调用堆栈就可以找出原因了,对应的案例,可以查看我的文章:
基于WebRTC构建的C++程序因虚拟内存不足导致闪退问题的排查以及解决办法的探究https://blog.csdn.net/chenlycly/article/details/133973572
3.2、内存不足导致new申请内存时抛出异常,引发程序崩溃
内存不足导致new申请内存失败,抛出异常,如果程序中安装了异常捕获模块,异常捕获模块就会感知到程序发生了异常。以我们项目遇到的一个问题为例,程序崩溃后取来了dump文件,用Windbg打开,查看异常发生的函数调用堆栈:
就是new时抛出了bad_alloc的异常,就是内存不足引起的。是因为程序中发生了内存泄漏,导致的内存不足。
对于引发C++程序内存泄漏的原因分析与排查方法,之前做过详细的总结,可以查看我之前写的文章:
引发C++程序内存泄漏的原因分析与排查方法总结https://blog.csdn.net/chenlycly/article/details/141403867 内存泄漏问题,有时排查起来会很费劲,可以借助一些工具去排查,比如使用Windbg、VLD、Debug Diagnostic Tool、Valgrind和AddressSanitizer等。
关于VLD检测内存泄漏的完整案例,可以查看我的文章:
使用Visual Leak Detector(VLD)排查C++程序内存泄漏https://blog.csdn.net/chenlycly/article/details/135472681 关于Debug Diagnostic Tool检测内存泄漏的案例,可以查看我的文章:
使用Debug Diagnostic Tool工具排查C++程序内存泄漏问题https://blog.csdn.net/chenlycly/article/details/80075888 关于Windbg检测内存泄漏的案例,可以查看我的文章:
使用Windbg排查C++程序内存泄漏问题https://blog.csdn.net/chenlycly/article/details/121295720使用 Windbg 的 !heap 命令分析内存泄漏
https://blog.csdn.net/chenlycly/article/details/131576063 内存泄漏点的定位,还可以使用历史版本比对法,相关方法可以查看我之前写的一篇类似的文章:
使用历史版本比对法排查C++程序中的内存泄漏问题https://blog.csdn.net/chenlycly/article/details/141002375此处的历史版本比对法,是排查C++软件异常的一个重要方法,之前对排查C++软件异常的常用手段与方法进行过详细的总结,可以查看我之前写的文章:
排查C++软件异常的常见思路与方法(实战经验总结)https://blog.csdn.net/chenlycly/article/details/120629327 关于Linux系统上的Valgrind和AddressSanitizer工具,可以查看我的文章:(微软从Visual Stdio 2019 19.6版本开始引入Google的AddressSanitizer内存检测工具,下面的文章有讲到)
Windows和Linux下排查C++软件异常的常用调试器与内存检测工具详细介绍https://blog.csdn.net/chenlycly/article/details/126381865为什么选择C/C++内存检测工具AddressSanitizer?如何使用AddressSanitizer?
https://blog.csdn.net/chenlycly/article/details/132863447 有时使用一个工具可能无法定位内存泄漏问题,可能需要尝试使用多个内存检测工具去排查,之前记录了内存泄漏排查的专题,感兴趣也可以去看看:
C++内存泄漏排查https://blog.csdn.net/chenlycly/category_12370029.html
4、引发内存不足的两个原因
导致程序产生内存不足,从项目中遇到的问题案例来看,主要有两种原因:
1)程序占用了大量的虚拟内存,接近给程序进程分配的虚拟内存的上限。
2)程序中发生了内存泄漏,导致程序占用的虚拟内存越来越大,接近或达到给程序进程分配的虚拟内存上限。
4.1、32位程序默认的用户态虚拟内存只有2GB,程序模块较多,可能占用的内存接近2GB了
32位程序启动时,系统会给程序分配4GB的虚拟内存,用户态和内核态默认各占2GB。如果程序中的模块比较多,或者引入了消耗内存很大的模块后,会导致主程序占用的内存很大,甚至接近用户态2GB虚拟内存的上限(程序的业务模块基本都运行在用户态中,占用的都是用户态的虚拟内存)。再执行比较耗内存的操作时,可能会导致更接近或达到2GB用户态虚拟内存的上限,导致内存不足,进而导致程序出问题。
规避的办法是,修改主程序的工程配置,启动大地址模式,将用户态虚拟内存从默认的2GB上调到3GB,这样可以有效地缓解内存不够用的问题。关于如何在Visual Studio中配置大地址模式,可以查看我之前写的文章:
如何配置32位C++程序启用大地址模式(将用户态虚拟内存从2GB扩充到3GB),以解决用户态虚拟内存不够用问题?(项目实战案例解析)https://blog.csdn.net/chenlycly/article/details/138460583
4.2、程序中有内存泄漏,且内存泄漏的代码在不断的执行,导致程序占用内存越来越多
程序中有内存泄漏,内存泄漏的代码频繁地被执行,或者用户多次执行内存泄漏的代码(也可能是测试人员进行拷机测试,比如不断的入会退会,前端时间我们就遇到过这个问题场景),导致程序占用的内存越来越多,最后导致内存不足。对于内存泄漏,可以使用Process Explorer工具持续地查看程序虚拟内存的变化,确定是否存在内存泄漏。找到内存泄漏的点并加以解决,就可以解决这类问题。
关于内存泄漏的排查,可以用历史版本比对法,也可以使用一些工具进行排查,上面已经讲到了,我就不再赘述了。
5、解决内存不够用的办法
我们先要确定引发内存不足的原因,然后针对原因和场景,提出对应的解决办法。如果程序中有内存泄漏,则要解决内存泄漏。如果程序是32位的,确实包含多个模块,占用的内存比较大,则有以下几个方法:
1)优化程序内存占用
对程序中的内存占用进行优化,减小内存的占用。
2)扩充用户态虚拟内存可以修改主工程的工程属性,将用户态的虚拟内存从2GB扩大到3GB,用规避的方法加以解决,如何扩充,可以查看我之前写的专题文章:
如何配置32位C++程序启用大地址模式(将用户态虚拟内存从2GB扩充到3GB),以解决用户态虚拟内存不够用问题?(项目实战案例解析)
https://blog.csdn.net/chenlycly/article/details/1384605833)将程序升级到64位
可以将程序升级到64位,但这里有个问题。虽然大家使用的基本都是Win10及以上的系统,都是64位的,但有的用户的电脑用的系统比较老,比如还在用Win7,可能还是32位的。做成64位程序,则没法在32位系统中运行。
4)做成多进程模式可以做成多进程,但多进程加大了程序的开发难度,使得开发难度和成本都变高了。有的程序就做成了多进程模式,最具代表性的就是Chrome浏览器,就做成了多进程模式,每个进程负责执行不同的事务。
6、最后
本文从最近遇到的两个内存不足导致程序异常的案例出发,详细讲述了案例中涉及到的细节与要点,并对内存不足相关内容进行了展开和总结,有一定的实战参考价值,希望能帮到大家。
相关文章:
内存不足引发C++程序闪退崩溃问题的分析与总结
目录 1、内存不足一般出现在32位程序中 2、内存不足时会导致malloc或new申请内存失败 2.1、malloc申请内存失败,返回NULL 2.2、new申请内存失败,抛出异常 3、内存不足项目实战案例中相关细节与要点说明 3.1、内存不足导致malloc申请内存失败&#…...
C++ 多态作业练习
作业1、 编写一个英雄类 class Hero{ int atk; int def; int spd; int hp; public: 所有的get set 方法 void equipWeapon(Weapon*) 根据传入的武器不同,英雄获得不同的属性加成 } #include <iostream> #include <cstring&g…...
(免费送源码)计算机毕业设计原创定制:Java+JSP+HTML+JQUERY+AJAX+MySQL springboot计算机类专业考研学习网站管理系统
摘 要 大数据时代下,数据呈爆炸式地增长。为了迎合信息化时代的潮流和信息化安全的要求,利用互联网服务于其他行业,促进生产,已经是成为一种势不可挡的趋势。在大学生在线计算机类专业考研学习网站管理的要求下,开发一…...
层次聚类(Hierarchical Clustering)详解
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...
Cannal实现MySQL主从同步环境搭建
大家好,我是袁庭新。 在多数情况下,客户端往往会优先获取缓存中的数据。然而,当缓存数据与数据库中的实际数据存在显著不一致时,可能会导致严重的后果。因此,确保数据库与缓存数据之间的一致性变得至关重要,…...
Js-函数-03
函数定义 在java中我们为了提高代码的复用性,可以使用方法。同样,在JavaScript中可以使用函数来完成相同的事情。JavaScript中的函数被设计为执行特定任务的代码块,通过关键字function来定义。 <!DOCTYPE html> <html lang"en…...
9.机器学习--SVM支持向量机
支持向量机(Support Vector Machine,SVM)是一种二分类监督学习模型。支持向量机最早在 1964 年被提出,1995年前后理论成熟并开始被大量应用与人像识别、文本分类等问题中。它的基本模型是定义在特征空间上的间隔最大的线性分类器&…...
探索Python的HTTP之旅:揭秘Requests库的神秘面纱
文章目录 **探索Python的HTTP之旅:揭秘Requests库的神秘面纱**第一部分:背景介绍第二部分:Requests库是什么?第三部分:如何安装Requests库?第四部分:Requests库的五个简单函数使用方法第五部分&…...
vue3项目使用动态表单formcreate
使用两个插件: 支持可视化设计的低代码表单组件 | FormCreate 好用的低代码可视化表单设计器 | FcDesigner 一、安装 1.使用 Node.js 引入 npm install form-create/element-ui npm install form-create/designer^3 npm install element-plus 2. main.js引入…...
指针的奥秘:深入探索内存的秘密
前言 在计算机编程的广阔天地中,指针作为一种独特的数据类型,它不仅是C语言的核心,也是理解计算机内存管理的基石。指针的概念虽然强大,但对于初学者来说,它常常是学习过程中的一个难点。本文旨在揭开指针的神秘面纱&a…...
车载摄像camera基础知识和评估
一、车载摄像头应用 以下是根据图片内容重新制作的表格: | 序号 | 产品用途 |------|---------------- | 1 | AVM/环视360摄像头 | 2 | DMS摄像头 | 3 | IMS/OMS摄像头 | 4 | RVC摄像头 | 5 | 红外夜视摄像头 | 6 | 底盘透明摄像头 | 7 …...
OpenCV 图像轮廓查找与绘制全攻略:从函数使用到实战应用详解
摘要:本文详细介绍了 OpenCV 中用于查找图像轮廓的 cv2.findContours() 函数以及绘制轮廓的 cv2.drawContours() 函数的使用方法。涵盖 cv2.findContours() 各参数(如 mode 不同取值对应不同轮廓检索模式)及返回值的详细解析,搭配…...
微信小程序WXSS全局样式与局部样式的使用教程
微信小程序WXSS全局样式与局部样式的使用教程 引言 在微信小程序的开发中,样式的设计与实现是提升用户体验的关键部分。WXSS(WeiXin Style Sheets)作为微信小程序的样式表语言,不仅支持丰富的样式功能,还能通过全局样式与局部样式的灵活运用,帮助开发者构建美观且易于维…...
Leetcode142. 环形链表 II(HOT100)
链接 我的错误代码: class Solution { public:ListNode *detectCycle(ListNode *head) {if(!head||!head->next)return nullptr;ListNode* f head->next,*s head;while(f){f f->next,s s->next;if(!f)return nullptr;f f->next;if(fs){ListNo…...
Java程序基础⑤Java数组的定义和使用+引用的概念
目录 1. Java数组的基本概念 1.1 数组的定义 1.2 数组存在的意义 1.3 数组的使用 1.4 二维数组 2. 引用类型JVM的内存分布 2.1 JVM的内存分布 2.2 基本数据类型和引用型数据类型的区别 2.3 引用注意事项 2.4 传值传递 3. 数组总结和应用场景 3.1 一维数组和二维数组…...
丁真杯理塘大赛题解
前言:部分代码思路可能与题解思路不同,请勿强行带入 真蛰虫 原题链接 1.一道非常基础的数学题。 2.主要就是在考察分解质因数。首先看真蛰虫的质因数是不是包含了容器的所有质因数,如果没有,那么就不能放入容器中。如果全部包…...
FPGA经验谈系列文章——8、复位的设计
前言 剑法往往有着固定的招式套路,而写代码似乎也存在类似的情况。不知从何时起,众多 FPGA 工程师们在编写代码时开启了一种关于 always 语句块的流行写法,那就是: always @(posedge i_clk or negedge i_rstn) 就笔者所经历的诸多项目以及所接触到的不少工程师而言,大家在…...
Android studio与JS交互
文章目录 前言一、html二、使用步骤1.2.AS 总结 前言 最近在使用Android Studio的WebView,有些功能要AS与JS交互。 一、html html文件 <!DOCTYPE html> <html> <!--javascript--> <head><meta charset"utf-8"><title>Carson…...
健身房小程序服务渠道开展
健身不单单是锻炼身体、保持身材,也是一种社交方式,城市里门店不少,每家都有一定流量和老客,但仅靠传统线下拉客/自然流量前往和线上朋友圈、短视频发硬广等方式还不够。 商家需要找到更多潜在目标客户,而消费者也对门…...
大宗商品行业区块链应用
应用场景 区块链技术具有透明性、去中心化、不可篡改等特点,因此可以在大宗商品定价方面得到应用。通过区块链技术,相关交易的各方可以在无需依赖中心化第三方的情况下,实时、准确地获取定价信息。这种技术的应用能够提高效率、降低成本、提…...
软考教材重点内容 信息安全工程师 第 5 章 物理与环境安全技术
5.1.1 物理安全概念 传统上的物理安全也称为实体安全,是指包括环境、设备和记录介质在内的所有支持网络信息系统运行的硬件的总体安全,是网络信息系统安全、可靠、不间断运行的基本保证,并且确保在信息进行加工处理、服务、决策支持的过程中&…...
蓝桥杯每日真题 - 第21天
题目:(空间) 题目描述(12届 C&C B组A题) 解题思路: 转换单位: 内存总大小为 256MB,换算为字节: 25610241024268,435,456字节 计算每个整数占用空间: 每个 32 位整数占用…...
【C++】C++11新特性详解:可变参数模板与emplace系列的应用
C语法相关知识点可以通过点击以下链接进行学习一起加油!命名空间缺省参数与函数重载C相关特性类和对象-上篇类和对象-中篇类和对象-下篇日期类C/C内存管理模板初阶String使用String模拟实现Vector使用及其模拟实现List使用及其模拟实现容器适配器Stack与QueuePriori…...
下载并安装Visual Studio 2017过程
一、下载 1、下载链接 下载链接:官方网址 先登录 往下滑找到较早的下载 2、进行搜索下载 或者直接点击🔗网站跳转 3、确认系统信息进行下载 二、安装 下载完成后右键使用管理员身份运行 1、点击同意后安装 2、若报错—设置失败 打开控制面板-&g…...
【消息序列】详解(6):深入探讨缓冲区管理与流量控制机制
目录 一、概述 1.1. 缓冲区管理的重要性 1.2. 实现方式 1.2.1. HCI_Read_Buffer_Size 命令 1.2.2. HCI_Number_Of_Completed_Packets 事件 1.2.3. HCI_Set_Controller_To_Host_Flow_Control 命令 1.2.4. HCI_Host_Buffer_Size 命令 1.2.5. HCI_Host_Number_Of_Complete…...
Java开发经验——Spring Test 常见错误
摘要 本文详细介绍了Java开发中Spring Test的常见错误和解决方案。文章首先概述了Spring中进行单元测试的多种方法,包括使用JUnit和Spring Boot Test进行集成测试,以及Mockito进行单元测试。接着,文章分析了Spring资源文件扫描不到的问题&am…...
麦肯锡报告 | 科技落地的真谛:超越技术本身的价值创造
科技创新正在以惊人的速度改变企业运作和客户体验,但实现其潜力的关键在于正确的策略、流程、文化和人才。麦肯锡强调了一个理念:Never just tech(不仅仅是技术)。这表明,成功的数字化转型不仅依赖于技术,还…...
React 常见问题解答:设置、安装、用户事件和最佳实践
在本文中,我们将回答您在开始使用 React 时可能会问的 9 个常见问题。 1、开始使用 React 需要哪些技能和知识? 在深入研究 React 之前,您应该对以下内容有深入的了解: HTML、CSS 和 JavaScript (ES6)&a…...
Mairadb 最大连接数、当前连接数 查询
目录 查询数据库 最大连接数 查询当前连接总数 环境 Mariadb 10.11.6 跳转mysql数据库: 查询数据库 最大连接数 show variables like max_connections; 注意; 这个版本不能使用 : show variables like ‘%max_connections%’; 会报错 ÿ…...
【R库包安装】R库包安装总结:conda、CRAN等
【R库包安装】R库包安装总结:conda、CRAN等 方法1:基于 R 的 CRAN 仓库安装CRAN库包查询从 CRAN 安装 方法2:使用conda安装库包确保已安装 R 和 Conda 环境使用 Conda 官网浏览是否存在相应库包Conda 安装 R 库 方法3:从 GitHub 安…...
php反序列化1_常见php序列化的CTF考题
声明: 以下多内容来自暗月师傅我是通过他的教程来学习记录的,如有侵权联系删除。 一道反序列化的CTF题分享_ctf反序列化题目_Mr.95的博客-CSDN博客 一些其他大佬的wp参考:php_反序列化_1 | dayu’s blog (killdayu.com) 序列化一个对象将…...
LabVIEW动态显示控件方案
在LabVIEW开发中,涉及到动态显示和控制界面的设计时,经常需要根据用户选择的不同参数来动态显示或隐藏相关控件。例如,某些能可能会根据“Type”控件的不同选择显示不同的参数,如“Target”、“Duration”和“EndType”等。在一个…...
游戏引擎学习第22天
移除 DllMain() 并成功重新编译 以下是对内容的详细复述与总结: 问题和解决方案: 在编译过程中遇到了一些问题,特别是如何告知编译器不要退出程序,而是继续处理。问题的根源在于编译过程中传递给链接器的参数设置不正确。原本尝试…...
GitLab|GitLab报错:PG::ConnectionBad: could not connect to server...
错误信息: PG::ConnectionBad: could not connect to server: No such file or directory Is the server running locally and accepting connections on Unix domain socket "/var/opt/gitlab/postgresql/.s.PGSQL.5432"? /opt/gitlab/embedded/service…...
Ray 和 PyTorch
Ray 和 PyTorch 的介绍 Ray 是什么? Ray 是一个用于 分布式计算和机器学习任务 的开源框架,提供了一个高效的、灵活的并行计算平台。它的核心功能是支持分布式计算,帮助开发者以简单的方式扩展 Python 应用程序。 Ray 适用于以下场景&…...
Qt之详解QLockFile 文件锁
文章目录 QLockFile 详解前言什么是 QLockFile?QLockFile 的构造函数和常用成员函数构造函数1. 指定锁文件路径的构造函数 常用成员函数1. lock2. unlock3. isLocked4. setStaleLockTime5. getLockInfo6. removeStaleLock 完整示例代码总结 QLockFile 详解 前言 在…...
从0开始学PHP面向对象内容之常用设计模式(组合,外观,代理)
二、结构型设计模式 4、组合模式(Composite) 组合模式(Composite Pattern)是一种结构型设计模式,它将对象组合成树形结构以表示”部分–整体“的层次结构。通过组合模式,客户端可以以一致的方式处理单个对…...
机械设计学习资料
免费送大家学习资源,已整理好,仅供学习 下载网址: https://www.zzhlszk.com/?qZ02-%E6%9C%BA%E6%A2%B0%E8%AE%BE%E8%AE%A1%E8%A7%84%E8%8C%83SOP.zip...
论文笔记3-XCube: Large-Scale 3D Generative Modeling using Sparse Voxel Hierarchies
目录 Abtract 相关工作 核心算法: 整体流程概述 具体流程解析 1. 输入(Input) 2. 稀疏结构 VAE(Sparse Structure VAE) 3.分层体素潜在扩散(Hierarchical Voxel Latent Diffusion)…...
【组件】前端ElementUi 下拉Tree树形组件 带模糊搜索自动展开高亮功能
【组件】前端ElementUi 下拉Tree树形组件 带模糊搜索自动展开高亮功能 https://live.csdn.net/v/435737 <template><div><el-popoverstyle"overflow-y: auto; "placement"bottom"trigger"click"><el-inputstyle"margi…...
诠视科技受邀出席“中国虚拟现实产学研大会”
2024年11月2-3日,由中国虚拟现实技术与产业创新平台举办的第十届“中国虚拟现实产学研大会” 在北京顺利召开,大会围绕“虚拟现实技术与产业创新融合”这一主题进行深入探讨。诠视科技作为虚拟现实产业的创新领军企业,CEO林瓊受邀参加本次活动…...
【达梦数据库】授权查询
目录 授权查询EXPIRED_DATECLUSTER_TYPE 更换原则更换方法 授权查询 select * from v$license;EXPIRED_DATE 过期日期,如果是正式版会显示NULL CLUSTER_TYPE 授权使用的集群类型CLUSTER_TYPE,格式为字符串“XXXX”, 每一位上 0 表示禁止…...
探索 ZED 双目 3D 相机发展:ZED 2i 的创新功能扩展之路
在科技迅速发展的当下,3D 视觉技术在众多领域的发展中有着重要作用。Stereolabs 公司研发的 ZED 相机受到广泛关注。Stereolabs 于 2010 年在美国旧金山成立,一直专注于立体视觉和 3D 深度相机技术的研究。2015 年推出的 ZED 相机为无人机、机器人等设备…...
基于卷积神经网络的白菜病虫害识别与防治系统,resnet50,mobilenet模型【pytorch框架+python源码】
更多目标检测和图像分类识别项目可看我主页其他文章 功能演示: 白菜病虫害识别与防治系统,卷积神经网络,resnet50,mobilenet【pytorch框架,python源码】_哔哩哔哩_bilibili (一)简介 基于卷…...
计算机网络 | 7.网络安全
1.网络安全问题概述 (1)计算机网络面临的安全性威胁 <1>计算机网络面临的完全性威胁 计算机网络面临的两大类安全威胁:被动攻击和主动攻击 被动攻击 截获:从网络上窃听他人的通信内容。主动攻击 篡改:故意篡改…...
Opencv+ROS自编相机驱动
目录 一、工具 二、原理 代码 标定 三、总结 参考: 一、工具 opencv2ros ubuntu18.04 usb摄像头 二、原理 这里模仿usb_cam功能包对Opencv_ros进行修饰,加上相机参数和相机状态,难点在于相机参数的读取。 对于相机参数话题 camera…...
js---函数参数是值传递还是引用传递
理解1:都是值(基本/地址值)传递 理解2:可能是值传递,也可能是引用传递(地址值) 在JavaScript中,函数参数的传递方式取决于参数的类型: 值传递(Pass by Val…...
如何解决DDoS导致服务器宕机?
分布式拒绝服务攻击(DDoS攻击)是一种常见的网络安全威胁,通过大量恶意流量使目标服务器无法提供正常服务。DDoS攻击可能导致服务器宕机,严重影响业务的正常运行。本文将详细介绍如何检测和防御DDoS攻击,防止服务器宕机…...
临床检验项目指标学习笔记
声明: 家有病人,记录此学习笔记仅为了更好照顾家人。本文不负责内容的准确性和版权。如果存在侵权、或不希望被转载的媒体或个人可与我们联系,我将立即进行删除处理。 血脂四项 [Q&A] 血脂四项 指导意义 测定血清中血脂含量,…...
代码管理之Gitlab
文章目录 Git基础概述场景本地修改未提交,拉取远程代码修改提交本地,远程已有新提交 GitIDEA引入Git拉取仓库代码最后位置 Git基础 概述 workspace 工作区:本地电脑上看到的目录; repository 本地仓库:就是工作区中隐…...