在我的混合模式 C++ 应用程序中,我注意到以下奇怪的效果:

  • 如果我在 Visual Studio 之外启动可执行文件,所有非托管全局变量都会被正确销毁。
  • 如果我在 Visual Studio 之外启动可执行文件,然后附加调试器,所有非托管全局变量都会被正确销毁。
  • 我在 Visual Studio 调试器中启动可执行文件,并非所有非托管全局变量似乎都被破坏了。

  • 我读到 .Net 有 2 秒的清理超时时间。这是为了整个非托管全局变量销毁吗?或者这是每个析构函数?

    我很确定这 2 秒超时是原因,因为当我在 doexit 方法的开头设置断点时,调试器会在应用程序退出时停止。
    但是,如果我在 doexit 函数末尾附近设置断点,则永远不会命中该断点。

    有没有办法从应用程序中更改这个 2 秒超时?问题是如果不是所有的全局变量都被破坏,我的内存泄漏检测系统会报告很多内存泄漏。

    编辑:

    这是一个显示问题的示例程序。

    由于我想制作一个混合模式的应用程序,我编写了一个单独的 main(本地编译)和一个单独的“add”函数(编译托管)。这是主要的:
    #include <iostream>
    #include <windows.h>
    
    extern int add(int,int);
    
    class X
       {
       public:
          X(char *name) : m_name(name) {std::cout << "Constructing " << m_name << std::endl;}
          ~X() {Sleep(1000); std::cout << "Destructing " << m_name << std::endl;}
       private:
          char *m_name;
       };
    
    X x1("x1");
    X x2("x2");
    X x3("x3");
    X x4("x4");
    X x5("x5");
    
    int main()
    {
    std::cout << "In beginning of main" << std::endl;
    int i = add(1,2);
    std::cout << i << std::endl;
    std::cout << "At end of main" << std::endl;
    }
    

    这是 add.cpp 文件:
    int add (int one, int two)
    {
    int result = one;
    result += two;
    return result;
    }
    

    它们使用以下命令编译和链接(使用 VS2010 和 .Net 4.0):
    cl /c /EHsc /Od /Zi main.cpp
    cl /c       /Od /Zi /clr add.cpp
    link /debug /debugtype:cv main.obj add.obj mscoree.lib nochkclr.obj /nodefaultlib:libcmt.lib
    

    这是应用程序运行时的输出:
    Constructing x1
    Constructing x2
    Constructing x3
    Constructing x4
    Constructing x5
    In beginning of main
    3
    At end of main
    Destructing x5
    

    所以全局变量的销毁在第一个之后停止。

    如果我将 sleep 从 1000 毫秒减少到 500 毫秒,全局变量 x5、x4 和 x3 会被破坏,但它也会停止。

    我将文件上传到 http://www.mediafire.com/?gil2hm2d3cw1zmz ,所以如果你想测试这个,你不必再次复制/粘贴或重新输入所有内容。

    编辑: 稍微更改了标题以使其更清楚,现在我们有了问题的实际原因。

    最佳答案

    嗯,确认问题。我需要考虑/阅读更多关于这个的信息。它开始看起来像一个错误,真的。

    注意 我从来没有在调试时运行过任何这些,因为我的 VS 设置不知何故被破坏了。感谢您进行命令行构建!

    作为记录,这是我在 Win7-64、.NET 4.0、两个 CPU 内核和 1Gb RAM 上的初始运行(无需重新编译,只是您的二进制文件):

    C:\stacko>.\main.exe
    Constructing x1
    Constructing x2
    Constructing x3
    Constructing x4
    Constructing x5
    In beginning of main
    3
    At end of main
    Destructing x5
    Destructing x4
    Destructing x3
    

    在本地再次编译它没有任何改变。我仔细检查了这确实是一个混合模式的神器:
    C:\stacko>cl /c /EHsc /Od /Zi main.cpp
    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    main.cpp
    
    
    C:\stacko>link main.obj
    Microsoft (R) Incremental Linker Version 10.00.30319.01
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    C:\stacko>.\main.exe
    Constructing x1
    Constructing x2
    Constructing x3
    Constructing x4
    Constructing x5
    In beginning of main
    At end of main
    Destructing x5
    Destructing x4
    Destructing x3
    Destructing x2
    Destructing x1
    

    检查:确认。

    关于.net - 由于 2 秒超时,并非所有本地全局变量都在混合模式 .Net 应用程序中被破坏,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6028884/

    10-11 22:54
    查看更多