Discussion on the Problems of incomplete application windows, soaring GDI objects, and GDI resource leakage

Source: Internet
Author: User
Tags sybase

Http://hi.baidu.com/qi_xian/blog/item/08011716e096751e962b4345.html

This article is reproduced in 3sdn:Http://www.3sdn.net

Sometimes, when an application runs for a certain period of time, the window may be incomplete (blurred screen), and the error "required resources cannot be obtained" may be annoying. At this point, if you open the resource manager, in "View", "Select column", add "GDI object", you can clearly see that as the program runs, the GDI object, quickly increase. When the number reaches 9999 (why is this number, as mentioned below), the program window interface will be incomplete, if you drag a scroll bar in the program, a serious screen may appear, and an incomplete warning box may appear, warning: "required resources cannot be obtained ".

This is a typical problem of GDI resource leakage.

The reason for this problem is that you have created a GDI object in the program, and it has not been released or destroyed. This problem usually occurs in onpaint (), draw (), and some functions that involve plotting. The following is an example:

1. A new GDI object is selected to DC, but the original GDI object in DC is not restored after use.
Cgdiobject * polddc = PDC-> SelectObject (& yourobject );
//......
PDC-> SelectObject (polddc); // At the end of the drawing, this sentence cannot be less

2. After using context CDC obtained through getdc (), it must be realcoded.

3. Create a bitmap object and then eobject ().

4. This is my problem: clistctrl is used to display the search result during file search. I want to display the file icon before the file name, so I use the function:

: Shgetfileinfo (pathname, file_attribute_normal, & SFI, sizeof (shfileinfo), role | shgfi_displayname | shgfi_typename | shgfi_icon | shgfi_smallicon ))

I got the icon of the file, but I didn't use it any more, so I didn't care about it. It was a "big mistake" and the consequences were unimaginable, as described above. The solution is to remove the red part. At this time, when running the program, the number of GDI objects is generally stable between 9999 and 35, and there will be no terrible phenomenon that will soar to in an instant.

The following describes the problem of the GDI object.

In order to solve the problem I encountered, I searched online for a long time, and finally saw henan_lujun (Network Name, cited from: http://www.programfan.com/club/showpost.asp? Id = 7995) analysis, understand a little bit, the following reprinted segment:

The GDI object is actually a Data Structure maintained by the Windows system. Based on stability and robustness, Microsoft handed over the management right of all GDI objects to the object manager of the Windows system for management. Users can only operate on these objects through the "handle" returned by the system.
In Windows 2000, the handle is actually a DWORD Value. The DWORD value is a 32-bit data, which is divided into two parts: Table index and uniqueness identifier, each of which occupies 16 digits. Therefore, theoretically, every process in windows, the maximum value of the accessible GDI object is 64 KB. However, in Windows 2000, the maximum number of customer handles is hard set to 16384 (16 k );
However, in Windows 2000, since the maximum number of client handles is hard set to 16384, why is the program interface messy when the number of GDI objects increases to 9999? Originally, in Windows 10000, the maximum value of the GDI object for each process was set to 10000 by default. According to Microsoft Data, it is to prevent the "bad" program from allocating too many resources. Therefore, when the GDI object reaches 9999, the program cannot create new GDI resources, every time a new resource is used to draw the interface, the program creates confusion.
However, in Windows 2000 and later operating systems, the maximum value of the GDI object that each process can create can be reset by modifying the Registry. In Windows 2000, the Registry item is "gdiprocesshandlequota" in HKEY_LOCAL_MACHINE/software/Microsoft/Windows NT/CurrentVersion/windows ". After the new value is set, restart the computer, and the number of GDI objects that each process can use in the system will change to the number you set.
However, the above statement is not completely correct!
According to a piece of Sybase data display (http://www.sybase.com/detail? Id = 1019174). In windwos2000, you can only fine-tune the value of "gdiprocesshandlequota". If the set value exceeds 15000, the system becomes unstable. In fact, I tested in Windows 2000. When the return value of the getguiresources function is 12288 (12 K), it is impossible to create a new GDI object. That is to say, in Windows 2000, when the total number of GDI objects in a process reaches 12288, a new GDI object cannot be created.
In Windows 2000, is the number of GDI objects that a process can create independent of each process, or is it limited by the Windows operating system? To this end, I wrote a check program, which creates a specified number of brush objects in batch, and counts the number of GDI objects in the process and the total number of GDI objects in the system, the running interface is as follows (the figure is not shown here, but it does not matter)

The code for the total GDI object in the statistics system is as follows:
Int getgdinuminsystem (void)
{
Int ngdinums = 0;/* sum of the GDI objects of all processes */
Int nprocess = 0;/* Number of processes in the system */

DWORD aproid [2, 1024];
DWORD cbneeded;
: Enumprocesses (aproid, sizeof (aproid), & cbneeded );

/* Total Number of processes in the system */
Nprocess = cbneeded/sizeof (DWORD );

/* Count the number of GDI objects of each process */
For (INT I = 0; I <nprocess; I ++)
{
Handle HPrO =: OpenProcess (process_query_information | process_vm_read, false, aproid [I]);

Ngdinums + =: getguiresources (HPrO, gr_gdiobjects );

Closehandle (HPrO );
}

Return ngdinums;
}

Use this check program to perform the following experiments:
① Modify the value of "gdiprocesshandlequota" in Windows 2000 to 12000;
② Start a check process and create 11000 GDI objects in it!
③ Enable the second check process (the first process is not closed) and create 11000 GDI objects.
The test results show that the object of the first process can be created smoothly, but the object of the second process cannot be created smoothly. This shows that in Windows 2000, the number of GDI objects that can be created by each process is not only limited within the process, but also limited by the entire operating system. Multiple experiments show that when the total number of GDI objects in Windows 2000 reaches a value after 15900, the process can no longer create a GDI object, and the system becomes unstable, as to the critical value, the results of each test were inconsistent, but they were all after 15900.

The above test was conducted in Windows 2000. What is the situation in Windows 2003? Go to the 2003 system and change the registry key "gdiprocesshandlequota" to 20000. Then run the test program and create 20000 GDI objects. Everything works! Change again, 30000, run, still normal ;...... The page rendering problem occurs only when the system is changed to 70000. In this case, we have to assume that Windows 2003 removes the limit of a client's GDI handle of up to 16 KB, but set the limit to 64 K?
To verify this speculation, I use the check program to directly create a 64 K GDI resource. The running result shows that after a process creates a certain GDI object, it cannot create a new GDI object, this indicates that the above speculation is not completely correct. However, based on the experiment experience in Windows 2000, I quickly thought that the GDI objects that can be created in Windows 2003 should be limited by the operating system, that is to say, in Windows 2003, the number of GDI objects that can be created by each process is relaxed, but the number of GDI objects in the system cannot exceed a certain value. To verify this result, perform the following test:
① Modify the value of "gdiprocesshandlequota" in Windows 2003 to 50000;
② Start a check process and create 40000 GDI objects in it!
③ Enable the second check process (the first process is not closed) and create 40000 GDI objects.
The test results are basically similar to those in Windows 2000. The only difference is that during the creation of a GDI object in the second process, creation fails only when the total number of GDI objects in the system reaches 63700. Similarly, the critical value is not fixed, but multiple tests show that when the total number of GDI objects reaches 63700, the system becomes unstable.

Conclusion
After the above analysis, we can know that in the Windows 2000/2003 operating system, each process can create a GDI object, depending on three factors: two restrictions on the system itself and the maximum limit set in the Windows registry.
First, the number of GDI objects that can be created by each process is theoretically 64 K. However, in Windows 2000, the system hard sets the number of GDI handles that can be created by the customer to a value not greater than 16 K, in fact, when the number of GDI objects reaches 12 kb, the system is abnormal. In Windows 2003, The system relaxed the limit on the number of GDI objects, makes the number of GDI objects that each process can use close to 64 K;

Secondly, the number of GDI objects that can be created by each process is also limited by the total number of GDI objects in the operating system. in Windows 2000, when the total number of GDI objects in the system reaches a value after 15900, the process can no longer create a new GDI object; in 20003, this value is increased to a value after 63700. However, the value is not fixed.

Finally, the maximum number of GDI objects that a process can create is limited by the value set by the "gdiprocesshandlequota" item in HKEY_LOCAL_MACHINE/software/Microsoft/Windows NT/CurrentVersion/windows in the registry, this value sets the maximum number of GDI objects that can be created by each process in windows. In Windows 2000 and 2003, the default value is 10000, this shows why the interface is messy when the number of GDI objects created by the Program reaches 9999.

Believe it, after reading it, you know what is going on.

In a word, a GDI/GDI + object is created. Release it after use!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.