首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++ _popen()窗口泄漏分页池内存

C++ _popen()窗口泄漏分页池内存
EN

Stack Overflow用户
提问于 2022-01-30 16:35:10
回答 1查看 124关注 0票数 0

主应用程序在Windows中运行,该进程启动其他c++控制台进程,但所有控制台模式都是隐藏的,即父进程是Windows,子进程是非控制台应用程序。

观察到的寻呼池内存在客户系统windows服务器2016调用_popen()期间不断增加。该应用程序运行在我们的实验室系统相同的操作系统。

在Windows性能工具xperf中,捕获日志并检查调用堆栈。随函附上图供参考。

代码语言:javascript
复制
void CMachine::GetJavaVersion()
{
m_stJavaVersion.m_strName = " Java version";

CPUChar strVersion[64] = { 0 };
BOOL bFound = CheckJREVersion(strVersion, 64);

BYTE bytColorSt = RED;
string strRemark;

FILE *fp = NULL;
char version[130] = { 0 };
BOOL bFoundVersion = FALSE;
fp = _popen("java -version 2>&1", "r");
while (fp && fgets(version, sizeof version, fp))
{
    string strTmp = version;
    if (strTmp.find("version") != string::npos)
    {
        bFoundVersion = TRUE;
        break;
    }
}
if(fp) _pclose(fp);

....

PoolMon跟踪

内存:33401164K可用:30057324K PageFlts: 92362 InRam Krnl:20212K P:776328K提交:3228052K限制:37595468K峰值:4747992K池N:182820K P:782568K系统池信息池类型配置类型配置

呼叫10546816 ( 390) 10319712 ( 382) 227104 324868080 ( 11392) 1430

CM31寻呼42886 ( 0) 20849 ( 0) 22037 101154816 ( 0) 4590

SeAt传呼44678436 (1662) 43769798 (1630) 908638 87253680 ( 3072) 96

QINi寻呼234 ( 0) 1( 0) 233 60293216 ( 0) 258769

MmSt传呼2683066 ( 79) 2670922 ( 83) 12144 27223856 ( 3312) 2241

PoolMon

EN

回答 1

Stack Overflow用户

发布于 2022-01-31 06:11:53

Eric写了关于基准错误的文章。我认为第一个错误适用于你的情况:

错误1:选择一个糟糕的指标。

为什么要测量“分页池”以确定内存泄漏?

分页内存是交换到磁盘上的内存。之所以会发生这种情况,是因为其他方面需要物理RAM。物理内存需要什么?可能用于运行您启动的进程。

一旦内存被交换到磁盘,它可能需要一段时间,直到它被交换回RAM。当其他应用程序试图访问内存时,这种情况就会发生--如果有的话,可能是几分钟。

我还倾向于说,内存不是在方法调用期间泄漏的,而是在方法调用之后泄漏的。方法调用后,应销毁所有变量,并释放相关资源。

如果你被告知寻呼池是原因,那就询问证据。

在我的Windows 10系统上,分页池限制为17 GB。这可以由配置符号的“视图/系统信息”中的Process显示。

如果您经常运行java -version,以致于它泄漏了17 GB的内核内存,那么就会出现严重的问题。当然,会有管道或其他东西将输出从Java重定向到您的应用程序,这样您就可以读取流。还有其他内核对象,如进程、线程等。

即使每次调用都有1 kB内核内存泄漏,也需要调用1700万次才能耗尽分页池。如果是这样的话,也许您应该考虑缓存结果。服务器管理员不太可能在几天内安装和卸载Java 1700万次。

为了监视分页池,可以尝试使用波尔蒙命令行参数。Poolmon是WDK的一部分。

代码中的问题:

您的代码至少有两个问题:

  1. 如果"version“从未出现在输出中,那么您的代码可能会在一个无休止的循环中运行。怎么会发生这种事?这是不太可能的,但是如果我把我的HelloWorld.exe重命名为java.exe,它就可以了。
  2. 如果"version“出现在输出中,但是"ver”意外地出现在第一个缓冲区中,而"sion“出现在第二个缓冲区中,那么您将永远不会发现它确实存在。您的代码可能会遇到无穷无尽的循环。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70916677

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档