FIX: Perdita di memoria nel driver ODBC per Jet con SQL_NUMERIC o SQL_C_BINARY dati

Traduzione articoli Traduzione articoli
Identificativo articolo: 273772 - Visualizza i prodotti a cui si riferisce l?articolo.
Espandi tutto | Chiudi tutto

In questa pagina

Sintomi

Una perdita di memoria si verifica quando si chiama la funzione SQLBindParameter nel driver ODBC di Jet e quando si associa a un tipo di dati SQL di SQL_NUMERIC o quando si associa SQL_C_BINARY a SQL_WCHAR.

Se si utilizza il Performance Monitor (PerfMon) per controllare il byte privati per il processo, vengono visualizzati un aumento della memoria graduale ma costante, e la memoria non viene liberata quando chiude le istruzioni o le connessioni.

Cause

Buffer vengono utilizzati all'interno il driver ODBC di Jet consente di convertire i tipi di dati di parametro ODBC tipi di dati nativo per il modulo di gestione di database Jet. I buffer vengono fatto riferimento tramite puntatori gestiti sull'handle di istruzione, come parte i descrittori di parametro (IPDs).

In genere, il codice verifica se il puntatore giÓ fa riferimento a un buffer di memoria valida e quindi riutilizza il buffer se esiste. Tuttavia, quando si associa un tipo di dati SQL_NUMERIC o, quando si esegue l'associazione SQL_C_BINARY a SQL_WCHAR nuova memoria Ŕ allocata e assegnata il puntatore del mouse senza verificare prima, e il valore precedente verrÓ sovrascritto.

Risoluzione

Questo problema Ŕ stato risolto nei service pack pi¨ recenti per Windows 2000 e MDAC 2.5.
  • Per risolvere questo problema Ŕ necessario ottenere la versione pi¨ recente del service pack per Windows 2000. Per ulteriori informazioni, fare clic sul numero dell'articolo della Microsoft Knowledge Base riportato di seguito riportato:
    260910Come ottenere Windows 2000 Service Pack pi¨ recente
  • Per risolvere il problema, ottenere il service pack pi¨ recente per Microsoft Data Access Components 2.5. Per ulteriori informazioni, fare clic sul numero dell'articolo della Microsoft Knowledge Base riportato di seguito riportato:
    293312INFORMAZIONI: Come ottenere il pi¨ recente MDAC 2.5 Service Pack
La versione inglese di questa correzione deve essere di avere i seguenti attributi di file o versioni successive:
   Date        Version       Size              File name    
   ---------------------------------------------------------------------
   09/13/00    4.0.5708.0    270,608 bytes    Odbcjt32.dll
   09/14/00    1.10.101.0    295,696 bytes    Q273772_W2K_SP2_x86_en.EXE
				
Nota : questo hotfix richiede Microsoft Data Access Components (MDAC) 2.5 Service Pack 1 (SP1) o successiva a causa delle dipendenze sugli altri file di introdotto con MDAC 2.5 SP1. Vi Ŕ alcuna correzione disponibili che Ŕ possibile applicare direttamente a MDAC 2.5.

Per installare questo aggiornamento rapido (hotfix) in una piattaforma di Microsoft Windows 2000, eseguire il pacchetto di installazione di aggiornamento rapido (hotfix) (Q273772_W2K_SP2_x86_en.EXE). Sebbene l'aggiornamento rapido stesso non Ŕ dipendente dalla piattaforma, il pacchetto di installazione aggiornamento rapido (hotfix) Ŕ progettato per essere eseguito solo su piattaforme Windows 2000 e non verrÓ eseguito in Microsoft Windows NT 4.0, Microsoft Windows 95 o piattaforme Microsoft Windows 98. MDAC contiene i file di file protetti di sistema ed Ŕ possibile sostituire solo i file da un programma di installazione hotfix con firma digitale in Windows 2000. Il file di aggiornamento rapido (hotfix) di autonomo viene fornito anche in modo che Ŕ possibile copiare il file direttamente su piattaforme Windows NT 4.0, Windows 95 o Windows 98.


PER RISOLVERE IL PROBLEMA

Non Ŕ disponibile alcuna soluzione per questo problema.

Status

Microsoft ha confermato che questo problema riguarda i prodotti Microsoft elencati all'inizio di questo articolo. Questo problema Ŕ stato innanzitutto corretto in Microsoft Data Access Components 2.5 Service Pack 2 e Microsoft Windows 2000 Service Pack 2.

Informazioni

Se si esamina la memoria per il processo periodicamente durante l'esecuzione del processo, si notare che un numero sempre maggiore di 0 x 100000 (1048576) allocazioni di byte. Se il processo continua a eseguire, il processo eventualmente esaurisce la memoria e non risponde (si blocca) o ha esito negativo.

Procedura per riprodurre il problema

  1. Copiare il codice che segue in un'applicazione console di Microsoft Visual c ++ e quindi compilare il codice. Si noti, che potrebbe essere necessario modificare il nome dell'origine dati, l'id utente e la password.
    #include <windows.h>
    #include <sql.h>
    #include <sqlext.h>
    #include <tchar.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    
    #define LEAK_NUMERIC 1		//Use this to determine NUMERIC or BINARY leak
    
    
    void HandleError(SQLHANDLE	hHandle, SQLSMALLINT hType, RETCODE RetCode)
    {
    	SQLSMALLINT	iRec = 0;
    	SQLINTEGER	iError;
    	TCHAR		szMessage[1000];
    	TCHAR		szState[SQL_SQLSTATE_SIZE];
    
    
    	if (RetCode == SQL_INVALID_HANDLE)
    	{
    		fprintf(stderr,"Invalid handle!\n");
    		return;
    	}
    
    	while (SQLGetDiagRec(hType,
    			 hHandle,
    			 ++iRec,
    			 (SQLCHAR *)szState,
    			 &iError,
    			 (SQLCHAR *)szMessage,
    			 (SQLSMALLINT)(sizeof(szMessage) / sizeof(TCHAR)),
    			 (SQLSMALLINT *)NULL) == SQL_SUCCESS)
    	{
    		fprintf(stderr,TEXT("[%5.5s] %s (%d)\n"),szState,szMessage,iError);
    	}
    
    }
    
    
    char* szConnStringIn = "Driver={Microsoft Access Driver (*.mdb)};DBQ=E:\\JetLeak\\TestDatabase.mdb";
    char* szDropTable = "DROP TABLE LeakTable";
    //char* szInsertStatement = "INSERT INTO LeakTable VALUES (?)";
    char* szSelectStatement = "SELECT * FROM LeakTable WHERE val1 = ?";
    const int nParamCount = 1; 
    
    #if LEAK_NUMERIC
    char* szCreateTable = "CREATE TABLE LeakTable (val1 long)";
    #else
    char* szCreateTable = "CREATE TABLE LeakTable (val1 varchar(10))";
    #endif
    
    
    
    void main(int argc, char* argv[])
    {
    	SQLHENV henv;
    	SQLHDBC hdbc;
    	SQLHSTMT hstmt;
    	SQLRETURN nstatus;
    
    	char szConnStringOut[1024];
    	SQLSMALLINT cbConnOut;
    	SQLINTEGER status[nParamCount];
    
    #if LEAK_NUMERIC
    	SQLCHAR szParam[nParamCount][10] = {"12345"};
    #else
    	BYTE szParam[nParamCount][10] = {0x31,0x33,0x34,0x39};
    #endif
        
    	//Not checking the return codes in some cases for clarity.
    	
    	nstatus = SQLAllocHandle(SQL_HANDLE_ENV,NULL,&henv);
    	nstatus = SQLSetEnvAttr(henv,SQL_ATTR_ODBC_VERSION,(SQLPOINTER) SQL_OV_ODBC3,0);
    	nstatus = SQLAllocHandle(SQL_HANDLE_DBC,henv,&hdbc);
    
    	nstatus = SQLDriverConnect(hdbc,
    			NULL,
    			(SQLCHAR*) szConnStringIn,
    			SQL_NTS,
    			(SQLCHAR*) szConnStringOut,
    			sizeof (szConnStringOut),
    			&cbConnOut,
    			SQL_DRIVER_COMPLETE);
    							
    	if (nstatus != SQL_SUCCESS && nstatus != SQL_SUCCESS_WITH_INFO)
    	{
    		HandleError(hdbc,SQL_HANDLE_DBC,nstatus);
    		return;
    	}
    
    	nstatus = SQLAllocHandle(SQL_HANDLE_STMT,hdbc,&hstmt);	
    
    	nstatus = SQLExecDirect(hstmt, (SQLCHAR*) szDropTable, SQL_NTS);
    	nstatus = SQLExecDirect(hstmt, (SQLCHAR*) szCreateTable, SQL_NTS);
    
    	if (!SQL_SUCCEEDED(nstatus))
    	{
    		HandleError(hstmt,SQL_HANDLE_STMT,nstatus);
    	}
    
    	int i;
    	//only one parameter in this case
    	for (i=0; i < nParamCount; i++)
    	{
    		status[i] = SQL_NTS;
    
    
    
    #if LEAK_NUMERIC
    		nstatus = SQLBindParameter(hstmt,
    			i+1,
    			SQL_PARAM_INPUT,
    			SQL_C_CHAR,	
    			SQL_NUMERIC, 
    			10, 
    			0,
    			szParam[i],
    			10,
    			&status[i]);
    #else
    
    		nstatus = SQLBindParameter(hstmt,
    			i+1,
    			SQL_PARAM_INPUT,
    			SQL_C_BINARY,	
    			SQL_WCHAR,
    			10, 
    			0,
    			szParam[i],
    			10,
    			&status[i]);
    #endif
    	
    	
    	}
    
    	nstatus = SQLPrepare(hstmt,(SQLCHAR*) szSelectStatement, SQL_NTS);
    	if (nstatus != SQL_SUCCESS)
    	{
    		HandleError(hstmt,SQL_HANDLE_STMT,nstatus);
    	}
    
    	for (i=0; i < 100000; i++)
    	{
    		if (i % 100 == 0)
    		{
    			printf("Selected %d times\n", i);
    			//printf("Inserted %d records\n", i);
    			Sleep(100);
    		}
    		nstatus = SQLExecute(hstmt);
    		if (nstatus != SQL_SUCCESS)
    		{
    			HandleError(hstmt,SQL_HANDLE_STMT,nstatus);
    		}
    
    		SQLFreeStmt(hstmt, SQL_CLOSE);
    	}
    
    	nstatus = SQLExecDirect(hstmt, (SQLCHAR*) "DELETE FROM LeakTable", SQL_NTS);
    	if (nstatus != SQL_SUCCESS)
    	{
    		HandleError(hstmt,SQL_HANDLE_STMT,nstatus);
    	}
    
    	SQLFreeStmt(hstmt, SQL_CLOSE);
    	SQLDisconnect(hdbc);
    
    }
    
    						
    Nota : ╚ possibile utilizzare la costante LEAK_NUMERIC per dimostrare il SQL_NUMERIC oppure SQL_C_BINARY perdita.
  2. Creare un nuovo vuoto verrÓ database come specificato dalla posizione nella stringa di connessione.
  3. Avviare l'esecuzione del codice e quindi utilizzare Performance Monitor per controllare il contatore Byte privati per il processo.

    Si noti che il contatore Byte privati raggiunge costantemente durante l'esecuzione del codice.

ProprietÓ

Identificativo articolo: 273772 - Ultima modifica: lunedý 26 settembre 2005 - Revisione: 2.2
Le informazioni in questo articolo si applicano a:
  • Driver Microsoft Open Database Connectivity per Access 4.0
  • Microsoft Data Access Components 2.5
  • Microsoft Data Access Components 2.5 Service Pack 1
Chiavi:á
kbmt kbhotfixserver kbqfe kbbug kbfix kbjet kbmdac250sp2fix kbwin2000presp2fix KB273772 KbMtit
Traduzione automatica articoli
Il presente articolo Ŕ stato tradotto tramite il software di traduzione automatica di Microsoft e non da una persona. Microsoft offre sia articoli tradotti da persone fisiche sia articoli tradotti automaticamente da un software, in modo da rendere disponibili tutti gli articoli presenti nella nostra Knowledge Base nella lingua madre dell?utente. Tuttavia, un articolo tradotto in modo automatico non Ŕ sempre perfetto. Potrebbe contenere errori di sintassi, di grammatica o di utilizzo dei vocaboli, pi¨ o meno allo stesso modo di come una persona straniera potrebbe commettere degli errori parlando una lingua che non Ŕ la sua. Microsoft non Ŕ responsabile di alcuna imprecisione, errore o danno cagionato da qualsiasi traduzione non corretta dei contenuti o dell?utilizzo degli stessi fatto dai propri clienti. Microsoft, inoltre, aggiorna frequentemente il software di traduzione automatica.
Clicca qui per visualizzare la versione originale in inglese dell?articolo: 273772
LE INFORMAZIONI CONTENUTE NELLA MICROSOFT KNOWLEDGE BASE SONO FORNITE SENZA GARANZIA DI ALCUN TIPO, IMPLICITA OD ESPLICITA, COMPRESA QUELLA RIGUARDO ALLA COMMERCIALIZZAZIONE E/O COMPATIBILITA' IN IMPIEGHI PARTICOLARI. L'UTENTE SI ASSUME L'INTERA RESPONSABILITA' PER L'UTILIZZO DI QUESTE INFORMAZIONI. IN NESSUN CASO MICROSOFT CORPORATION E I SUOI FORNITORI SI RENDONO RESPONSABILI PER DANNI DIRETTI, INDIRETTI O ACCIDENTALI CHE POSSANO PROVOCARE PERDITA DI DENARO O DI DATI, ANCHE SE MICROSOFT O I SUOI FORNITORI FOSSERO STATI AVVISATI. IL DOCUMENTO PUO' ESSERE COPIATO E DISTRIBUITO ALLE SEGUENTI CONDIZIONI: 1) IL TESTO DEVE ESSERE COPIATO INTEGRALMENTE E TUTTE LE PAGINE DEVONO ESSERE INCLUSE. 2) I PROGRAMMI SE PRESENTI, DEVONO ESSERE COPIATI SENZA MODIFICHE, 3) IL DOCUMENTO DEVE ESSERE DISTRIBUITO INTERAMENTE IN OGNI SUA PARTE. 4) IL DOCUMENTO NON PUO' ESSERE DISTRIBUITO A SCOPO DI LUCRO.

Invia suggerimenti

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com