[VB6] Probleem met geheugengebruik Microsoft.Jet.OLEDB.4.0

Pagina: 1
Acties:

  • pjonk
  • Registratie: November 2000
  • Laatst online: 29-12-2025
Momenteel ben ik bezig met een Access 2000 gebaseerde applicatie die benaderd wordt via ADO 2.8 library. Deze applicatie heeft een importeer functie die vaak grote hoeveelheden records met (rond de 25000) wegschrijft in een tabel.
Nu blijkt dat de applicatie bij grote importbestanden onstabiel wordt en soms crasht. Ook is te zien dat de applicatie zeer veel geheugen snoept (soms 100MB!) tijdens het schrijven van de records. Het geheugen wordt meestal pas na een minuut of 5 weer vrijgegeven ondanks dat de connectie met de database wordt gesloten.

Na gegoogled te hebben kwam ik uit op het volgende MS artikel:
http://support.microsoft....aspx?scid=kb;en-us;248014

Alles wat in dit artikel staat komt overeen met mijn probleem. Als oplossing zegt MS het volgende:
The Max Buffer Size property control is the maximum amount of memory that can be used by the read-ahead/write-ahead Jet cache.

RESOLUTION
Set the Jet OLE DB:Max Buffer Size property to a value such as 2048 kilobytes. When using ADO, the property must be set after opening the connection.
Ook geeft MS voorbeeldcode waarmee ik een simpel programma heb gemaakt die records wegschrijft in een lusje.
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Private Sub Command1_Click()
Dim conn As New Connection
Dim x As String

conn.Open "provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & App.Path & "\MyDB.mdb"
conn.Properties("Jet OLEDB:Max Buffer Size") = 2048

x = String$(1000, "x")
conn.Execute "DELETE FROM MyTable", , adExecuteNoRecords
For i = 1 To Val(txtNumRecords)
   conn.Execute "INSERT INTO MyTable (Tekst) VALUES('" & x & "')", , adExecuteNoRecord
   Command1.Caption = "Writing record " & i
   DoEvents
Next i

conn.Close
Set conn = Nothing
End Sub

Afbeeldingslocatie: http://home.quicknet.nl/qn/prive/jonkie.xl/gotimg/jet4test.png

Deze simpele app schrijft het aantal aangegeven weg in een tabel met een auto ID en een Tekst veld.
Geheugen voor het schrijven van 25000 records
Afbeeldingslocatie: http://home.quicknet.nl/qn/prive/jonkie.xl/gotimg/voor.png

Geheugen na het schrijven van 25000 records
Afbeeldingslocatie: http://home.quicknet.nl/qn/prive/jonkie.xl/gotimg/na.png

De oplossing om de "Jet OLEDB:Max Buffer Size" aan te passen heeft bij mij geen effect. Het geheugengebruik is hetzelfde als ik deze property niet wijzig. Misschien dat iemand dit probleem kent of een andere oplossing kan aandragen.? Thanx

[ Voor 4% gewijzigd door pjonk op 30-12-2005 15:47 ]

It’s nice to be important but it’s more important to be nice


  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 14:20

gorgi_19

Kruimeltjes zijn weer op :9

De veelheid geheugen, kwam dat niet doordat VB6 een eigen GC had?

Digitaal onderwijsmateriaal, leermateriaal voor hbo


  • pjonk
  • Registratie: November 2000
  • Laatst online: 29-12-2025
gorgi_19 schreef op zaterdag 08 januari 2005 @ 15:41:
De veelheid geheugen, kwam dat niet doordat VB6 een eigen GC had?
Het is in dit geval niet VB, maar de msjet40.dll die het geheugen vasthoudt zoals ik goed kan zien in de Sysinternals Project Explorer. Ook zegt MS in het artikel dat de read-ahead/write-ahead cache van de jet engine het probleem zou veroorzaken. Maar zoals ik al zei werkt de aangedragen oplossing om de buffer size op te geven helaas niet.

It’s nice to be important but it’s more important to be nice


  • pjonk
  • Registratie: November 2000
  • Laatst online: 29-12-2025
Niemand die ervaring heeft met dit probleem :?

It’s nice to be important but it’s more important to be nice


Verwijderd

Wat is het effect als je i.p.v. een SQL INSERT INTO gebruik gaat maken van
conn.addnew
conn!veld1="bla"
conn!veld2="bla"
conn.update
(ik weet niet zeker of het direct met conn. kan anders eerst een recordset maken en daarbij .addnew gebruiken)
conn.update is hierbij misschien ook niet elke iteratie nodig waardoor het sneller zou kunnen gaan.

  • pjonk
  • Registratie: November 2000
  • Laatst online: 29-12-2025
Verwijderd schreef op zondag 09 januari 2005 @ 20:15:
Wat is het effect als je i.p.v. een SQL INSERT INTO gebruik gaat maken van
conn.addnew
conn!veld1="bla"
conn!veld2="bla"
conn.update
(ik weet niet zeker of het direct met conn. kan anders eerst een recordset maken en daarbij .addnew gebruiken)
conn.update is hierbij misschien ook niet elke iteratie nodig waardoor het sneller zou kunnen gaan.
De oorspronkelijke code (die dus ook problemen geeft) maakte ook van deze methode gebruik. Het probleem lijkt het hem echt in de MS Jet engine te zitten. In plaats van de update in een loop uit te voeren weet ik dat er ook een updatebatch method wordt ondersteund waar ik nog even mee wil experimenteren.
Clearly, the Recordset must support batch updating. When a Recordset is in batch updating mode, all of the changes and new additions are saved in a local cache until the BatchUpdate method is called.
Ook ben ik naar andere alternatieven aan het kijken bijv het genereren van een batch SQL file door de applicatie. Die SQL file wil ik dan door het DBMS laten verwerken. Ik zit hier alleen met een Access DB en niet met een SQL Server oid. Access heeft naar mijn weten geen command line interface om een SQL file te verwerken. In MySQL gebruikte ik ook wel eens het LOAD DATA commando, maar dat ondersteunt Access ook niet.
Mocht iemand andere goede alternatieven weten zijn deze zeer welkom. :>

It’s nice to be important but it’s more important to be nice


Verwijderd

Kan je in de taskmanager de VM size (private bytes) kolom es aanzetten? Dat is namelijk de enige teller die er echt toe doet. In je screenshots zie ik je total commit charge maar een kleine 3 mb de lucht in schieten dus het lijkt er op dat je memory limit prima werkt.

  • pjonk
  • Registratie: November 2000
  • Laatst online: 29-12-2025
Verwijderd schreef op zondag 09 januari 2005 @ 22:54:
Kan je in de taskmanager de VM size (private bytes) kolom es aanzetten? Dat is namelijk de enige teller die er echt toe doet. In je screenshots zie ik je total commit charge maar een kleine 3 mb de lucht in schieten dus het lijkt er op dat je memory limit prima werkt.
Bij veel updates crasht de applicatie en soms ook de hele VB IDE. Dus dat lijkt met niet echt lekker. :'(
Maar goed ben nu aan het kijken naar een andere oplossing. Wat ik nu probeer is om meerdere SQL commands in een string te zetten, bijv:
code:
1
2
INSERT INTO MyTables VALUES (1,'hoi');
INSERT INTO MyTables VALUES (2,'doei');

Als ik deze via conn.Execute probeer uit te voeren lijkt dit niet te werken, want Access zegt dat hij nog data vind na het 1e SQL command. Lijkt er dus op dat ik geen multipe SQL commands kan uitvoeren. Ook als ik direct in de SQL editor in Access deze commando's probeer uit te voeren werkt het niet. Kan iemand mij vertellen of Access dit ondersteunt, want ik kan hierover niets vinden.

It’s nice to be important but it’s more important to be nice


  • pjonk
  • Registratie: November 2000
  • Laatst online: 29-12-2025
Inmiddels weer even geleden, maar ik heb de oplossing gevonden die ik natuurlijk met jullie wil delen. In een paar threads, gevonden met Google discussion groups, werd aangeraden om DAO batch updates te gebruiken ipv na elk record een update uit te voeren. Resultaat: een performance boost en geen geheugenproblemen meer _/-\o_
Een code sample heb ik van de MSDN site geplukt:
http://msdn.microsoft.com...htm/mdmthupdatebatchx.asp

It’s nice to be important but it’s more important to be nice

Pagina: 1