Windows 未释放系统资源

Windows 未释放系统资源,windows,resources,Windows,Resources,Windows 7上似乎没有返回系统资源,我遇到了一个问题。我用C编写了一个简短的测试程序,除了创建一堆窗口,然后在无限循环中销毁它们之外,什么都不做。在循环的每次迭代之后,“任务管理器”窗口中的句柄数将上升,并且永远不会返回到起始值。而且,所使用的内存也会逐渐增加。在运行程序足够长的时间后,程序崩溃。最终,我需要能够创建和销毁OpenGL上下文。如果我在这个简单的测试应用程序中包括OpenGL,除了它更快地使用资源外,其他行为都是一样的。我错过什么了吗 // ResourceTest.cpp

Windows 7上似乎没有返回系统资源,我遇到了一个问题。我用C编写了一个简短的测试程序,除了创建一堆窗口,然后在无限循环中销毁它们之外,什么都不做。在循环的每次迭代之后,“任务管理器”窗口中的句柄数将上升,并且永远不会返回到起始值。而且,所使用的内存也会逐渐增加。在运行程序足够长的时间后,程序崩溃。最终,我需要能够创建和销毁OpenGL上下文。如果我在这个简单的测试应用程序中包括OpenGL,除了它更快地使用资源外,其他行为都是一样的。我错过什么了吗

// ResourceTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "../GL/gl.h"
#include "../GL/glext.h"
#include "../GL/wglew.h"

typedef struct _WindowInfo {
    int x, y;
    int width, height;
    GLboolean visible;
    char *title;
    HWND hWnd;
    HDC device_context;
    GLint id;
    GLint pixelFormat;
    HGLRC hglrc;
} WindowInfo;

typedef GLboolean (APIENTRY *ChoosePixelFormatARBFunc_t)(HDC, GLint *, GLfloat *,  GLuint, GLint *, GLuint *);

ChoosePixelFormatARBFunc_t ChoosePixelFormatARB_func;

#define WINDOW_NAME window->title

HANDLE windowDestroyed;

LONG WINAPI MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    /* int w,h; */
    switch ( uMsg )
    {
        case WM_CREATE:
        {
            HDC hDC;
            int attribList[100];
            float fattribList[] = { 0.0, 0.0 };
            int i = 0;
            WindowInfo *window =
                (WindowInfo *)(((LPCREATESTRUCT)lParam)->lpCreateParams);
            PIXELFORMATDESCRIPTOR *ppfd = NULL;

            hDC = GetDC(hWnd);
            if (window->pixelFormat <= 0)
            {
                PIXELFORMATDESCRIPTOR pfd = {
                    sizeof(PIXELFORMATDESCRIPTOR),  /*  size of this pfd */
                    1,                              /* version number */
                    PFD_DRAW_TO_WINDOW |            /* support window */
                    PFD_DOUBLEBUFFER   |
                    PFD_SUPPORT_OPENGL,             /* support OpenGL */
                    PFD_TYPE_RGBA,                  /* RGBA type */
                    32,                             /* 24-bit color depth */
                    0, 0, 0, 0, 0, 0,               /* color bits ignored */
                    0,                              /* no alpha buffer */
                    0,                              /* shift bit ignored */
                    1,
                    0, 0, 0, 0,                     /* accum bits ignored */
                    24,                              /* set depth buffer     */
                    8,                              /* set stencil buffer */
                    0,                              /* no auxiliary buffer */
                    PFD_MAIN_PLANE,                 /* main layer */
                    0,                              /* reserved */
                    0, 0, 0                         /* layer masks ignored */
                };
                attribList[i++] = WGL_DRAW_TO_WINDOW_EXT;
                attribList[i++] = GL_TRUE;
                attribList[i++] = WGL_ACCELERATION_EXT;
                attribList[i++] = WGL_FULL_ACCELERATION_EXT;
                attribList[i++] = WGL_COLOR_BITS_EXT;
                attribList[i++] = 24;
                attribList[i++] = WGL_RED_BITS_EXT;
                attribList[i++] = 1;
                attribList[i++] = WGL_GREEN_BITS_EXT;
                attribList[i++] = 1;
                attribList[i++] = WGL_BLUE_BITS_EXT;
                attribList[i++] = 1;
                attribList[i++] = WGL_DOUBLE_BUFFER_EXT;
                attribList[i++] = GL_TRUE;
                attribList[i++] = WGL_DEPTH_BITS_EXT;
                attribList[i++] = 1;
                /* End the list */
                attribList[i++] = 0;
                attribList[i++] = 0;

                ppfd = &pfd;
                if (ChoosePixelFormatARB_func)
                {
                    GLuint numFormats;
                    ChoosePixelFormatARB_func(hDC, attribList, fattribList,
                        1, &window->pixelFormat, &numFormats);
                }
                else
                {
                    /* Okay, we were loaded manually.  Call the GDI functions. */
                    window->pixelFormat = ChoosePixelFormat(hDC, ppfd);
                }
            }
            else
            {
                PIXELFORMATDESCRIPTOR p;
                ppfd = &p;
                DescribePixelFormat(hDC, window->pixelFormat,
                    sizeof(PIXELFORMATDESCRIPTOR), ppfd);
            }
            if (window->pixelFormat)
            {
                SetPixelFormat(hDC, window->pixelFormat, ppfd);
            }
        }
        break;
    }

    return DefWindowProc( hWnd, uMsg, wParam, lParam );
}

DWORD WINAPI createWindow(LPVOID args)
{
    WindowInfo *window = (WindowInfo *)args;
    HINSTANCE hinstance;
    WNDCLASS  wc;
    DWORD     window_style;
    MSG msg;
    char name[32];
    HANDLE windowCreated;
    static int id;

    sprintf(name, "createwindow%d", window->id);
    windowCreated = OpenEvent(EVENT_ALL_ACCESS, FALSE, name);
    windowDestroyed = CreateEvent(NULL, TRUE, FALSE, NULL);
    hinstance = GetModuleHandle( NULL );
    if (!hinstance)
    {
        printf( "Couldn't get the module handle.\n" );
        return GL_FALSE;
    }

    if (!GetClassInfo(hinstance, "Test_Window", &wc)) 
    {
        wc.style = CS_OWNDC;
        wc.lpfnWndProc = (WNDPROC) MainWndProc;
        wc.cbClsExtra = 0;
        wc.cbWndExtra = 0;
        wc.hInstance = hinstance;
        wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
        wc.hCursor = LoadCursor( NULL, IDC_ARROW );
        wc.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
        wc.lpszMenuName = NULL;
        wc.lpszClassName = "Test_Window";

        if (!RegisterClass(&wc))
        {
            printf( "Couldn't register window class.\n" );
        }
    }

    window_style = WS_POPUP;

    window->hWnd = CreateWindowA( "Test_Window", WINDOW_NAME, window_style,
        window->x, window->y, window->width, window->height, NULL, NULL, hinstance,
        window);

    if ( !window->hWnd )
    {
        printf( "Create Window failed!.\n" );
    }
    window->device_context = GetDC(window->hWnd);

    if (window->visible)
    {
        ShowWindow(window->hWnd, SW_SHOWNORMAL);
    }

    SetEvent(windowCreated);

    while (GetMessage(&msg, NULL, 0, 0))
    {
        if (msg.hwnd == window->hWnd)
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    CloseHandle(windowCreated);
    window->hWnd = NULL;
    window->device_context = 0;
    SetEvent(windowDestroyed);
    return 0;
}

GLboolean createTestWindow(WindowInfo *window )
{
    HANDLE windowCreated;
    char name[32];

    sprintf(name, "createwindow%d", window->id);
    printf("Create window %d\n", window->id);
    windowCreated = CreateEvent(NULL, TRUE, FALSE, name);

    CreateThread(NULL, 2000, createWindow, (LPVOID)window, 0, NULL);
    WaitForSingleObject(windowCreated, 50000);
    CloseHandle(windowCreated);
    printf("Window created\n");
    return GL_TRUE;
}

int _tmain(int argc, _TCHAR* argv[])
{
    HWND hWnd;
    WindowInfo window[34];
    char windowTitle[34];
    int i;
    static int id = 1;

    // Create a window
    window[0].id = 1;
    window[0].x = 40;
    window[0].y = 600;
    window[0].width  = 800;
    window[0].height = 600;
    window[0].visible = 0; // wait to make window visible
    window[0].pixelFormat = 9;
    window[0].title = _strdup("Window 0");
    createTestWindow(&window[0] );
//  Create a context
//  window[0].hglrc = wglCreateContext((HDC)window[0].device_context );
//  wglMakeCurrent(window[0].device_context, window[0].hglrc);
//  Load function pointers
//  ChoosePixelFormatARB_func =
//      (ChoosePixelFormatARBFunc_t)wglGetProcAddress("wglChoosePixelFormatARB");
    // Destroy context
    // wglMakeCurrent(window[0].device_context, 0);
    // wglDeleteContext(window[0].hglrc);
    // DeleteDC(window[0].device_context);
    // Destroy window
    PostMessage(window[0].hWnd, WM_QUIT, 0, 0);
    free(window[0].title);

    while (1)
    {
        for (i = 0; i < 34; i++)
        {
            // Create 34 windows
            window[i].id = i + 1;
            window[i].x = 40;
            window[i].y = 600;
            window[i].width  = 800;
            window[i].height = 600;
            window[i].visible = 1; // wait to make window visible
            window[i].pixelFormat = 9;
            sprintf(windowTitle, "Window %d", window[i].id);
            window[i].title = _strdup(windowTitle);
            createTestWindow(&window[i] );
            // Create 34 contexts
//          window[i].hglrc = wglCreateContext((HDC)window[i].device_context );
//          wglMakeCurrent(window[i].device_context, window[i].hglrc);
        }
        Sleep(3000);
        for (i = 0; i < 34; i++)
        {
            // Destroy contexts
//          wglMakeCurrent(window[i].device_context, 0);
//          wglDeleteContext(window[i].hglrc);
//          DeleteDC(window[i].device_context);
            // Destroy windows
            PostMessage(window[i].hWnd, WM_QUIT, 0, 0);
            Sleep(100);
            printf("%s destroyed\n", window[i].title);
            free(window[i].title);
        }
        Sleep(2000);
    }
    return 0;
}
//ResourceTest.cpp:定义控制台应用程序的入口点。
//
#包括“stdafx.h”
#包括“windows.h”
#包括“./GL/GL.h”
#包括“./GL/glext.h”
#包括“./GL/wglew.h”
类型定义结构\u窗口信息{
int x,y;
int宽度、高度;
可见;
字符*标题;
HWND-HWND;
HDC设备上下文;
闪烁id;
闪烁像素格式;
HGLRC HGLRC;
}窗口信息;
typedef GLboolean(apiterm*选择像素格式函数)(HDC、GLint*、GLfloat*、GLint、GLint*、GLint*);
选择Pixelformatarbfunc\u t选择Pixelformatarbfunc;
#定义窗口名称窗口->标题
处理窗口被破坏;
长WINAPI MainWndProc(HWND HWND、UINT uMsg、WPARAM WPARAM、LPARAM LPARAM)
{
/*int w,h*/
开关(uMsg)
{
案例WM_创建:
{
HDC-HDC;
int吸引子[100];
float-fattribList[]={0.0,0.0};
int i=0;
WindowInfo*窗口=
(WindowInfo*)(((LPCREATESTRUCT)lParam)->lpCreateParams);
PIXELFORMATDESCRIPTOR*ppfd=NULL;
hDC=GetDC(hWnd);
if(窗口->像素格式-像素格式和numFormats);
}
其他的
{
/*好的,我们是手动加载的。调用GDI函数*/
窗口->像素格式=选择像素格式(hDC、ppfd);
}
}
其他的
{
像素点;
ppfd=&p;
描述像素格式(hDC,窗口->像素格式,
sizeof(像素格式描述符),ppfd;
}
如果(窗口->像素格式)
{
设置像素格式(hDC,窗口->像素格式,ppfd);
}
}
打破
}
返回DefWindowProc(hWnd、uMsg、wParam、lParam);
}
DWORD WINAPI createWindow(LPVOID参数)
{
WindowInfo*窗口=(WindowInfo*)参数;
HINSTANCE HINSTANCE;
WNDCLASS wc;
德沃德窗式;
味精;
字符名[32];
创建句柄窗口;
静态int-id;
sprintf(名称,“创建窗口%d”,窗口->id);
windowCreated=OpenEvent(事件\所有\访问,FALSE,名称);
windowDestroyed=CreateEvent(NULL、TRUE、FALSE、NULL);
hinstance=GetModuleHandle(NULL);
如果(!hinstance)
{
printf(“无法获取模块句柄。\n”);
返回GL_FALSE;
}
如果(!GetClassInfo(hinstance,“测试窗口”和wc))
{
wc.style=CS_OWNDC;
wc.lpfnWndProc=(WNDPROC)mainddproc;
wc.cbClsExtra=0;
wc.cbWndExtra=0;
wc.hInstance=hInstance;
wc.hIcon=LoadIcon(空,IDI_应用程序);
wc.hCursor=LoadCursor(空,IDC_箭头);
wc.hbrBackground=(HBRUSH)GetStockObject(黑色画笔);
wc.lpszMenuName=NULL;
wc.lpszClassName=“测试窗口”;
如果(!注册表类(&wc))
{
printf(“无法注册窗口类。\n”);
}
}
窗口样式=WS\u弹出窗口;
window->hWnd=CreateWindowA(“测试窗口”、窗口名称、窗口样式、,
窗口->x,窗口->y,窗口->宽度,窗口->高度,NULL,NULL,hinstance,
窗口);
如果(!window->hWnd)
{
printf(“创建窗口失败!”\n);
}
window->device\u context=GetDC(window->hWnd);
如果(窗口->可见)
{
ShowWindow(窗口->hWnd,SW_SHOWNORMAL);
}
SetEvent(windowCreated);
while(GetMessage(&msg,NULL,0,0))
{
如果(msg.hwnd==窗口->hwnd)
{
翻译信息(&msg);
发送消息(&msg);
}
}
CloseHandle(windowCreated);
窗口->hWnd=NULL;
窗口->设备上下文=0;
SetEvent(windowdestromed);
返回0;
}
GLboolean createTestWindow(WindowInfo*窗口)
{
创建句柄窗口;
字符名[32];
sprintf(名称,“创建窗口%d”,窗口->id);
printf(“创建窗口%d\n”,窗口->id);
windowCreated=CreateEvent(NULL、TRUE、FALSE、name);
CreateThread(NULL,2000,createWindow,(LPVOID)window,0,NULL);
WaitForSingleObject(windowCreated,50000);
CloseHandle(windowCreated);
printf(“创建的窗口”);
返回GL_TRUE;
}
int _tmain(int argc,_TCHAR*argv[]
{
HWND-HWND;
WindowInfo窗口[34];
标题[34];
int i;
静态int-id=1;
//创建一个窗口
窗口[0]。id=1;
窗口[0],x=40;
窗口[0],y=600;
窗口[0],宽度=800;
窗口[0],高度=600;
窗口[0]。可见=0;//等待使窗口可见
窗口[0]。像素格式=9;
窗口[0]。标题=_strdup(“窗口0”);
createTestWindow(&window[0]);
//创建上下文
//窗口[0]。hglrc=wglCreateContext((HDC)窗口[0]。设备上下文);
//wglMakeCurrent(窗口[0]。设备上下文,窗口[0]。hglrc);
//加载函数指针
//选择Pixelformatarb_func=
//(选择PixelFormatArbFunc_t)wglGetProcAddress(“wglChoosePixelFormatARB”);
//破坏上下文
//wglMakeCurrent(窗口[0]。设备上下文,0);
//wglDeleteContext(窗口[0].hglrc);
//DeleteDC(窗口[0]。设备上下文);
//破坏窗口
PostMessage(窗口[0].hWnd,WM_QUIT,0,0);
免费(窗口[0]。标题);
而(1)
{
对于(i=0;i<34;i++)
{
//创建34 wi