GDI Limitations Overview

Recentemente, ho avuto l’opportunità di affrontare un problema legato all’utilizzo delle risorse GDI, Graphics Device Interface, in una applicazione Win32 client/server.

 

Scenario

Ricevo, da un cliente, una segnalazione di errore sul programma che gestisce l’elaborazione e la stampa del registro fiscale di magazzino. Tale funzione elabora i movimenti (carichi e scarichi), secondo una particolare logica applicativa, e produce in output un report di stampa riepilogativo che giustifica la giacenza dei prodotti in un determinato momento del periodo fiscale.

L’errore restituito era un Access Violation, ossia la lettura di una zona di memoria protetta, non più disponibile o in uso da un’altra applicazione diversa dal programma che sta tentando di accedervi.

Dopo aver circoscritto il problema, abbiamo identificato la procedura che generava l’errore, si trattava della procedura di costruzione del report di stampa. Dopo aver elaborato un numero elevato di pagine (non fisso, ma sempre vicino alle 4.000 pagine) la funzione di costruzione del report restituiva l'Access Violation. Da subito abbiamo cercato di individuare possibili dispersioni di memoria che potessero creare problemi, ma non abbiamo trovato, nel software, nulla di anomalo.

L’errore è stato rilevato principalmente su client con SO Microsoft Windows XP.

 

Causa

Gli oggetti GDI vengono utilizzati dalla procedura di stampa per la costruzione delle pagine (da stampare) in una immagine virtuale complessiva (residente in memoria e strutturata come indicato nel report di stampa) destinata alla stampa o alla memorizzazione su file (PDF ad esempio).

Nel link riportato di seguito (sezione Limitations), viene ricordato che esiste una soglia massima di oggetti GDI che il sistema è in grado di gestire correttamente per l’elaborazione delle immagini in un task.

Per il SO Microsoft Windows XP e successivi questo limite (soglia) è fissato by default a 10.000 oggetti GDI e può essere consultato dal Task Manager nella colonna GDI Objects, come illustrato in figura 1.

GDI Objects 

Figura 1 - Oggetti GDI per task

Con l’impostazione di default, SO Microsoft Windows XP e report di stampa riguardante il registro fiscale di magazzino, la nostra applicazione riesce a gestire correttamene (al massimo) 4.000 pagine circa.

Da non dimenticare quando riportato nella sezione Limitations della definizione, fornita da wikipedia, per le risorse GDI:

http://en.wikipedia.org/wiki/Graphics_Device_Interface

"GDI objects varies from one version of Windows to the next: Windows 95, 98, and Millennium had a limit of 1,200 total objects; Windows 2000 has a limit of 16,384 objects; and Windows XP, Vista, and Windows 7 have a configurable limit (via the registry) that defaults to 10,000 objects per process (but a theoretical maximum of 65,536 for the entire session)."

Il problema è causato dunque da questo: quando un’applicazione raggiunge (e supera) il limite massimo degli oggetti GDI gestibili, secondo le impostazioni del SO, viene interrotta.

 

Soluzione (per SO diversi da XP, Vista, Windows 7)

Passare a sistemi operativi più recenti, perché nei SO precedenti a Microsoft XP il limite massimo degli oggetti GDI gestibili da un’applicazione non è configurabile.

 

Soluzione (per SO XP, Vista, Windows 7)

Aumentare il limite massimo degli oggetti GDI gestibili da un’applicazione.

Per quest’operazione è necessario modificare due chiavi nel Registry, come indicato nel seguente post di Mike Dopp:

http://weblogs.asp.net/mikedopp/archive/2008/05/16/increasing-user-handle-and-gdi-handle-limits.aspx

 

Conclusioni

Nella situazione descritta, aumentando da 10.000 a 15.000 il numero di oggetti GDI gestiti (con SO Microsoft Windows XP), tutte le elaborazioni di stampa vanno a buon file, anche la procedura di elaborazione e stampa del registro fiscale di magazzino.

Abbiamo impostato un limite inferiore al massimo consentito per non interferire con la stabilità del sistema.

 

Published venerdì 21 gennaio 2011 0.44 by sgovoni
Filed under: , ,

Comments

No Comments