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