Düzeltme: Jet ODBC sürücüsü SQL_NUMERIC veya SQL_C_BINARY veri bellek sızıntısı

Makale çevirileri Makale çevirileri
Makale numarası: 273772 - Bu makalenin geçerli olduğu ürünleri görün.
Hepsini aç | Hepsini kapa

Bu Sayfada

Belirtiler

Jet ODBC sürücüsü içinde SQLBindParameter işlevini çağırdığınızda ve SQL veri türü SQL_NUMERIC veya için SQL_WCHAR SQL_C_BINARY bağlamak için bağladığınızda, bellek sızıntısı oluşuyor.

Işlemi için özel bayt sayısını izlemek için performans izleyicisi'ni (PerfMon) kullanırsanız, artırma bellek zaman içinde WPA'ya, ancak sürekli bakın ve deyimleri veya bağlantıları kapattığınızda bellek serbest bırakılmaz.

Neden

Arabellekleri Jet ODBC sürücüsü içinde yerel veri türleri Jet veritabanı alt yapısı için ODBC parametre veri türleri dönüştürmek amacıyla kullanılır. Bu bir arabellek üzerinden işaretçileri deyimi tutamacı parametresi tanımlayıcılarının (IPDs) bir parçası olarak saklanır başvurulur.

Normal olarak, kodun işaretçiyi zaten geçerli bellek arabelleği başvurur ve varsa, arabelleği yeniden kullanır denetler. Ancak, SQL_NUMERIC veri türü bağlanırken veya SQL_C_BINARY SQL_WCHAR için bağlanırken, yeni bir bellek ayrılmış ve işaretçiyi ilk denetlemeden atanan ve önceki değeri yazılır.

Çözüm

Bu sorun en son hizmet paketleri Windows 2000 ve MDAC 2.5 düzeltildi.
  • Bu sorunu gidermek için, en son Windows 2000 hizmet paketini edinin. Ek bilgi için, Microsoft Bilgi Bankası'ndaki makaleyi görüntülemek üzere aşağıdaki makale numarasını tıklatın:
    260910En son Windows 2000 hizmet paketi nasıl elde edilir
  • Bu sorunu gidermek için <a0></a0>, Microsoft Data Access Components 2.5 için en son hizmet paketini edinin. Ek bilgi için, Microsoft Bilgi Bankası'ndaki makaleyi görüntülemek üzere aşağıdaki makale numarasını tıklatın:
    293312BILGI: son MDAC 2.5 nasıl elde edilir hizmet paketi
Bu düzeltmenin ingilizce sürümünde aşağıdaki dosya öznitelikleri olmalıdır veya daha yenisi:
   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
				
Not: Bu düzeltme, Microsoft Data Access Components (MDAC) 2.5 Service Pack 1 (SP1) gerektirir, veya daha sonra diğer dosyalara bağımlılıklar nedeniyle MDAC 2.5 SP1'de kullanılmaya başlandı. MDAC 2.5 için doğrudan uyguladığınız kullanılabilir bir düzeltme vardır.

Bir Microsoft Windows 2000 platformunda bu düzeltmenin yüklenebilmesi için <a0></a0>, düzeltme yükleme paketiyle (Q273772_W2K_SP2_x86_en.EXE) çalıştırın. Düzeltmeyi kendi kendine platform bağlı olmasa da, düzeltme yükleme paketiyle yalnızca Windows 2000 platformlar üzerinde çalışmak üzere tasarlanmıştır ve Microsoft Windows NT 4.0, Microsoft Windows 95 veya Microsoft Windows 98 platformlarının çalışmayacak. MDAC, sistem dosya korumalı dosyaları içerir ve bu dosyaları yalnızca Windows 2000'de bir dijital olarak imzalanmış bir düzeltme yükleyicisi tarafından değiştirebilirsiniz. Böylece, bu dosyayı doğrudan Windows NT 4.0, Windows 95 veya Windows 98 platformlarının kopyalayabilirsiniz bağımsız düzeltme dosyasını da sağlanır.


Geçici Çözüm

Bu soruna yönelik yok bir geçici çözüm vardır.

Durum

Microsoft, bu makalenin başında listelenen Microsoft ürünlerinde bir sorun olduğunu onaylamıştır. Bu sorun ilk olarak Microsoft Data Access Components 2.5 Service Pack 2 ve Windows 2000 Service Pack 2'de giderilmiştir.

Daha fazla bilgi

Çalışırken belirli aralıklarla işlemi çalışır işlem için bellek incelerseniz, gördüğünüz 0x100000 (1048576) sayısı bayt ayırma. Işlemi çalışmaya devam eder, işlemin sonunda bellek yetersiz çalıştırır ve yanıt vermiyor (Kilitleniyor) veya başarısız.

Davranışı yeniden oluşturma adımları

  1. Bir Microsoft Visual C++ konsol uygulamasına aşağıdaki kodu kopyalayın ve sonra kodu derleyin. Veri kaynağı adı, kullanıcı kimliği ve parolayı değiştirmek gerekebileceğini unutmayın.
    #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);
    
    }
    
    						
    Not: LEAK_NUMERIC sabit SQL_NUMERIC veya SQL_C_BINARY sızıntısı göstermek için kullanabilirsiniz.
  2. Yeni boş bir Microsoft Access veritabanı belirtilen konumunu bağlantı dizenizde oluşturun.
  3. Kod çalışan'ı başlatın ve sonra işlemi için özel bayt sayacı izlemek için performans izleyicisi'ni kullanın.

    Kod çalıştığı sırada özel bayt sayacı steadily artar olduğunu unutmayın.

Özellikler

Makale numarası: 273772 - Last Review: 26 Eylül 2005 Pazartesi - Gözden geçirme: 2.2
Bu makaledeki bilginin uygulandığı durum:
  • Access 4.0 için Microsoft Open Database Connectivity Sürücüsü
  • Microsoft Data Access Components 2.5
  • Microsoft Data Access Components 2.5 Service Pack 1
Anahtar Kelimeler: 
kbmt kbhotfixserver kbqfe kbbug kbfix kbjet kbmdac250sp2fix kbwin2000presp2fix KB273772 KbMttr
Machine-translated Article
ÖNEMLİ: Bu makale, bir kişi tarafından çevrilmek yerine, Microsoft makine-çevirisi yazılımı ile çevrilmiştir. Microsoft size hem kişiler tarafından çevrilmiş, hem de makine-çevrisi ile çevrilmiş makaleler sunar. Böylelikle, bilgi bankamızdaki tüm makalelere, kendi dilinizde ulaşmış olursunuz. Bununla birlikte, makine tarafından çevrilmiş makaleler mükemmel değildir. Bir yabancının sizin dilinizde konuşurken yapabileceği hatalar gibi, makale; kelime dağarcığı, söz dizim kuralları veya dil bilgisi açısından yanlışlar içerebilir. Microsoft, içeriğin yanlış çevrimi veya onun müşteri tarafından kullanımından doğan; kusur, hata veya zarardan sorumlu değildir. Microsoft ayrıca makine çevirisi yazılımını sıkça güncellemektedir.
Makalenin İngilizcesi aşağıdaki gibidir:273772

Geri Bildirim Ver

 

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