Toon posts:

[VB.NET] waarom neemt dit >50MB geheugen in

Pagina: 1
Acties:
  • 368 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
.NET heeft een garbage collector, dus hoef ik in principe geen object op nothing te gaan zetten.
Maar dit simpel database readertje heeft meer dan 50MB nodig 8)7
Er zitten wel 10.000 records in de tabel, maar dat mag toch geen rol spelen?
Er worden maar een 25 records effectief weggeschreven, de rest geraakt zelfs nooit in die If() selectie

btw: ik heb die database niet ontworpen, de klant/product/transporteur/chauffeur zitten allemaal in hetzelfde veld in dezelfde tabel, met een veldje dat aanduidt welk van de vier het is...
Hetzelfde voor die > en < fix, een isgelijkaan teken aanvaardt die db niet


de code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
Dim connectionstring As String = "Driver={Microsoft Paradox Driver (*.db )};DriverID=538;Fil=Paradox 4.X;DefaultDir=" & _dbpath & ";Dbq=" & _dbpath & ";CollatingSequence=International"
            Dim oCon As New OdbcConnection(connectionstring)
            oCon.Open()
            Dim ocmd As New OdbcCommand("SELECT * FROM MOVE ORDER BY Date1 ASC, Time1 ASC", oCon)
            Dim dbreader As OdbcDataReader = ocmd.ExecuteReader
            Dim sw As New StreamWriter(Environment.CurrentDirectory & "/output.txt")
            Dim i As Integer = 0
            While dbreader.Read
                If ((dbreader.GetValue(15) = _datum1) Or (dbreader.GetValue(15) = _datum2)) Then
                    Dim chauffeurnr As Object = dbreader.GetValue(7)
                    Dim transportnr As Object = dbreader.GetValue(4)
                    Dim productcode As Object = dbreader.GetValue(5)
                    Dim klantnr As Object = dbreader.GetValue(3)

                    Dim chauffeur As String = ""
                    Dim transporteur As String = ""
                    Dim product As String = ""
                    Dim klant As String = ""

                    Try
                        If (Not IsDBNull(klantnr)) Then klant = New OdbcCommand("SELECT String1 FROM BASE WHERE File>0 And File<2 AND code='" & klantnr & "'", oCon).ExecuteScalar()
                    Catch ex As Exception
                        Console.WriteLine("Kon 'klant' niet ophalen:" & ex.Message)
                    End Try
                    Try

                        If (Not IsDBNull(chauffeurnr)) Then chauffeur = New OdbcCommand("SELECT String1 FROM BASE WHERE File>4  AND File<6 AND code='" & chauffeurnr & "'", oCon).ExecuteScalar()
                    Catch ex As Exception
                        Console.WriteLine("Kon 'chauffeur' niet ophalen:" & ex.Message)
                    End Try
                    Try

                        If (Not IsDBNull(transportnr)) Then transporteur = New OdbcCommand("SELECT String1 FROM BASE WHERE File>1 AND File<3 AND code='" & transportnr & "'", oCon).ExecuteScalar()
                    Catch ex As Exception
                        Console.WriteLine("Kon 'transporteur' niet ophalen:" & ex.Message)
                    End Try
                    Try
                        If (Not IsDBNull(productcode)) Then product = New OdbcCommand("SELECT String1 FROM BASE WHERE File>2 AND File<4 AND code='" & productcode & "'", oCon).ExecuteScalar()
                    Catch ex As Exception
                        Console.WriteLine("Kon 'product' niet ophalen:" & ex.Message)
                    End Try

                    Dim sb As New StringBuilder()
                    sb.Append(dbreader.GetValue(0) & ";") '   nr
                ' nog wat appends, eigenlijk zou ik die ";" ook moeten appenden ipv &-en
                    sw.WriteLine(sb.ToString)
                End If
            End While
            sw.Close()
            oCon.Close()

  • whoami
  • Registratie: December 2000
  • Laatst online: 00:54
Tja, waarom ... .da's moeilijk te zeggen als we alleen de code zien.
Zowiezo sluit je ook je DataReader niet als je 'm niet meer nodig hebt.

Trouwens, is het niet beter om die extra queries die je in je loop doet, niet te doen ? In de plaats kan je die ene query kunnen aanpassen met wat left joins, zodanig dat alles in één keer opgehaald wordt.

https://fgheysels.github.io/


Verwijderd

Topicstarter
Tja, waarom ... .da's moeilijk te zeggen als we alleen de code zien.
wat wil je nog meer zien dan? Of hoe onderzoek je zoiets

en hoe doe je zoiets met een left join?
database is namelijk zo gemaakt:

tabelletje
code:
1
2
3
4
5
6
7
code veld1
1      eenproduct
2      eenchauffeur
3      eenleverancier
3      eenandereleverancier
4      eenklant
4      eenandereklant


die code bepaald de functie van veld1

[ Voor 29% gewijzigd door Verwijderd op 18-05-2007 11:25 ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 00:54
Met een profiler kan je dat verder onderzoeken.

Hoe doe je dat met left-joins:
code:
1
2
3
4
5
select alle-velden-uit-alle-tabellen-die-je-wil-hebben
from order
left join base as chauffeur on chaffeur.code = order.klantnr and file ...
left join base as transporteur on transporteur.code = order.transportnr and file ...
...

https://fgheysels.github.io/


  • Sybr_E-N
  • Registratie: December 2001
  • Laatst online: 21:54
Verwijderd schreef op vrijdag 18 mei 2007 @ 11:12:
.NET heeft een garbage collector, dus hoef ik in principe geen object op nothing te gaan zetten.
Dat is al een foute aaname.

Het is erg leuk en handig dat er een GC is, maar het is beter om disposable typen zelf vrij te geven in plaats van dat aan de GC over te laten. (Dus je moet zelf een odbcdatareader sluiten dmv close of dispose).

Waarom denk je dat juist dit stukje code 50MB vraagt? Zou het ook zo kunnen zijn dat er een stuk .NET framework wordt meegeladen?

Als je echt wilt weten wat je applicatie doet kun je met een profiler aan de gang gaan. Om even je eerste aanname in werking te zien moet je de volgende demo eens gaan bekijken. http://msdn.microsoft.com...0050217CLRPS/manifest.xml
Dan zie je meteen wat een Dispose methode doet, en waarom je dat zou moeten doen.

Verwijderd

Topicstarter
die datareader disposen zal toch niet veel uitmaken, die wordt enkel op 't einde gesloten
die sub odbccommands mogen eigenlijk ook niet veel uitmaken, want die worden misschien 15 keer gexecuted, alhoewel ik het eens met een left join ga proberen thx whoami

die profiler ga ik ook eens uittesten, zoiets kende ik nog niet
normaal dispose ik enkel graphics objecten en dingen waarvan ik weet dat je 't beter zelf doet, bij databases had ik er echter nog nooit issues mee gehad.

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 07:23

gorgi_19

Kruimeltjes zijn weer op :9

http://blogs.msdn.com/tes...of-memory-exceptions.aspx
De methodiek kan je iig gebruiken :)

Sowieso de blog van Tess een aanrader om te lezen :)

Digitaal onderwijsmateriaal, leermateriaal voor hbo


  • Xiphalon
  • Registratie: Juni 2001
  • Laatst online: 01-12 16:44
op regel 10-20 maak je voor elke regel in de tabel een 10tal objecten aan. Wat met een aantal regels al snel heel veel objecten wordne.
Hoewel .net inderdaad een garbage collector heeft, gaat die pas af als het nodig is, dus als je geheugen tekort komt, waardoor de objecten dus blijven bestaan.

Het zou beter moeten gaan als je de objecten hergebruikt, door de creatie buiten de lus te doen.

  • whoami
  • Registratie: December 2000
  • Laatst online: 00:54
Verwijderd schreef op vrijdag 18 mei 2007 @ 11:58:
die datareader disposen zal toch niet veel uitmaken, die wordt enkel op 't einde gesloten
Als ik naar jouw code kijk, zie ik toch niet dat hij gesloten wordt. Vanzodra je 'm niet meer nodig hebt (van zodra dat je 'm dus volledig doorlopen hebt (want je kan toch niet meer terugkeren), zou je hem beter sluiten.

https://fgheysels.github.io/


Verwijderd

Topicstarter
zonder regel 10-20 is het nog maar 35MB !
dus die left joins ga ik zeker doen
meer flushes of minder strings doen veranderen niets

enkel de database connection openen: 17MB
het sql statement uitvoeren en datareader openen: 35MB

of OLEDB minder verbruikt dan ODBC kan ik niet testen, mijn database wil niet met oledb praten..

[ Voor 5% gewijzigd door Verwijderd op 18-05-2007 13:02 ]


  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 07:23

gorgi_19

Kruimeltjes zijn weer op :9

Ik gok sowieso dat je niet echt lager komt dan 30 MB (het zou me althans verbazen); .Net heeft ook een hoop overhead wat geheugen in neemt.

Digitaal onderwijsmateriaal, leermateriaal voor hbo


Verwijderd

Topicstarter
klopt, maar het verbaasde me dat er ineens 50, en zelfs 60MB stond.
mijn andere applicaties lopen met objecten uit de SQLClient namespace en die applicaties komen amper boven de 30, terwijl die een form hebben, 500 records terugkrijgen uit 250.000 records en elk record nog es naar een eigen type wordt omgezet.
Vandaar mijn verbazing dat een simpel commandline programma al zoveel opslokte

  • Mastermind
  • Registratie: Februari 2000
  • Laatst online: 29-11 15:35
Je kunt using gebruiken om het geheugen schoon te houden. Kijk hier eens naar:
http://davidhayden.com/blog/dave/archive/2005/01/13/773.aspx

  • Shezzie
  • Registratie: Januari 2005
  • Laatst online: 01-12 11:21

Shezzie

Lekker hoor!

Kijk de hoeveelheid references/namespaces van je project eens na, loop je niet op de achtergrond een boel stiekem bij te laden? Een simpel SQL-progje(db->xls) is slechts 12Mb RAM groot hier; een programma voor orderpikken(Exact SDK, Crystal Reports e.d.) wordt echter wel ruim 70Mb als ik het alleen maar opstart.

  • whoami
  • Registratie: December 2000
  • Laatst online: 00:54
Mastermind schreef op vrijdag 18 mei 2007 @ 14:46:
Je kunt using gebruiken om het geheugen schoon te houden. Kijk hier eens naar:
http://davidhayden.com/blog/dave/archive/2005/01/13/773.aspx
using is een C# keyword; dit gaat over VB.NET. :)

https://fgheysels.github.io/


  • Serpie
  • Registratie: Maart 2005
  • Laatst online: 01-07-2023
whoami schreef op zaterdag 19 mei 2007 @ 00:47:
[...]

using is een C# keyword; dit gaat over VB.NET. :)
In VB.NET 2.0 mogen wij deze ook gebruiken ;)
Wat ik ook vaak frapant vind is dat het geheugen bij dotnet applicaties zoveel afneemt als je deze minimaliseert.

  • Remus
  • Registratie: Juli 2000
  • Laatst online: 15-08-2021
Serpie schreef op zaterdag 19 mei 2007 @ 08:51:
[...]

Wat ik ook vaak frapant vind is dat het geheugen bij dotnet applicaties zoveel afneemt als je deze minimaliseert.
Dat gebeurt niet alleen bij dotnet applicaties. En het geheugen gebruik neemt niet daadwerkelijk af, maar het geheugen wordt dan simpelweg gepaged naar je virtueel geheugen (dat niet wordt gerekend tot de betreffende kolom in taakbeheer). Als je de applicatie vervolgens weer maximaliseert en kort gebruikt zit je in no-time weer op hetzelfde geheugengebruik.

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Het is dus ook onzin om te kijken naar de Mem Usage kolom in de Task Manager als je wilt weten hoeveel geheugen een applicatie nodig heeft. Dan kan je beter kijken naar de VM Size kolom.

We adore chaos because we like to restore order - M.C. Escher

Pagina: 1