Toon posts:

[VB]Array te groot - out of memory

Pagina: 1
Acties:

Verwijderd

Topicstarter
Het project:

Code is veel te lang. Ik zal dus een beschrijving doen waarin het stukje onderaan voorkomt.

Hardware:
16*80 ledmatrix, aagestuurd door een 80c59 controller. Verbonden via de FT245BM USB <> 8bit FiFo aan pc.
Bevat een E²prom met 64K waarin de bitmaps opgeslagen zitten (1260 bytes + 1 optie byte)
Deze matrix is "bitmap-gestuurd". De controller wordt gebruikt om de bitmap data telkens op zijn uitgangen te zetten. Er zit dus geen karaktergenerator in. Het is de software die alle bitmaps moet maken.

Software:
Programma gemaakt in Visual Basic. Dit programma zet teksten/afbeeldingen om in bitmaps (array's van 1260 bits, die elk een ledje voorstellen). Die bitmaps worden 1-malig doorgestuurd naar de E²prom via de FTB245 chip tijdens een interrupt.

Ik wil een image array aanmaken van 1260 images (16x80). De bedoeling is dat deze images een LEDmatrix voorstellen. Als de gebruiker klikt op zo'n LED (1 image dus), dan verandert de kleur van wit<>rood. Momenteel heb ik al verschillende deelprogramma's gemaakt die panelen (stuk van een ledmatrix) voorstellen. De image array's hebben hier een grootte van 10x14.
Deze deelprogramma's kan ik perfect doen werken, het aantal images is dus niet teveel.


Mijn probleem:
Nu wil ik ook een programma hebben waarin de gebruiker een overzicht heeft op de ganse matrix: 1280 leds (16x80 orientatie).

Ik gebruik dezelfde code, maar vergroot de variabelen:


code:
1
2
3
4
5
'deze code in de form load

For Y = 1 To 1280
    Load imgPixel(Y)  'alle 1280 images
Next Y


naast de imgPixel array, heb ik een tabel die coherent is aan de imgPixel array
code:
1
Dim KarakterSet(1260) As Boolean  'public declaration


Als de gebruiker klikt op een image, wordt er gekeken naar de overeenkomstige waarde in tabel "Karakterset". Met behulp van deze
tabel wordt gekeken of de led op rood of wit moet komen te staan.


tot zover geen probleem; nu komt het:
Deze code maakt mijn pixelarray dynamisch aan. Echter zijn er teveel objecten.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
For Y = 1 To Hoogte   'hoogte is hier 16
        For X = 1 To Breedte   'Breedte is hier 80


            imgPixel(I).Visible = True
                
                If KarakterSet(I) = True Then        'true = 0 = lamp brandt
                    imgPixel(I).Picture = LoadPicture(Padnaam & "\wit.bmp")
                Else
                    imgPixel(I).Picture = LoadPicture(Padnaam & "\rood.bmp")
                End If
            imgPixel(I).Visible = True
            imgPixel(I).Left = X * 250 + (X - 1) * imgPixel(1).Width
            imgPixel(I).Top = Y * 250 + (Y - 1) * imgPixel(1).Top
            imgPixel(I).Refresh
            I = I + 1

        Next X
Next Y



Resultaat:
Ik krijg de melding "Out of memory -runtime error '7' " De debugger stopt bij element 851.
De code zelf (de geneste lussen) kloppen. Verander ik de hoogte en breedte om terug te gebruiken in mijn deelprogramma's, dan werkt alles perfect.

Wat heb ik al geprobeerd?
-Proberen te werken met een Flexgrid; maar echt onhandig in gebruik om dezelfde look&feel te geven van de matrix
-Google gezocht: users die klagen over memory leaks in VB? tot extra RAM bijsteken :?
-GoT Search; geen echt resultaat gevonden.

Specs werkpc
Win98; PIII 550Mhz, 256MB SDRAM

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 13:27
Heb je ook al het geheugengebruik werkelijk gemeten? Heb je dus wel echt te weinig geheugen of heb je een te kleine swap file o.i.d.?

  • Sjaaky
  • Registratie: Oktober 2000
  • Laatst online: 22-04 07:04
Ik denk dat je uit geheugen loopt omdat je 1260 images in het geheugen laadt. Klinkt niet echt als veel images, maar goed het volgende zou moeten schelen:

pseudocode:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
PictureWit = LoadPicture(Padnaam & "\wit.bmp")
PictureRood = LoadPicture(Padnaam & "\rood.bmp")

loop y 
  loop x
    ...
    If KarakterSet(I) = True Then           
       imgPixel(i).Picture = PictureWit
    else
       imgPixel(i).Picture = PictureRood
    end
  endloop
endloop


edit:
Bovendien is de code om je imgPixels te positioneren nogal vaag. Als VB dynamisch een of ander canvas gaat resizen om dit te kunnen laten zien, kom je hiermee redelijk snel aan je geheugengrenzen.

[ Voor 21% gewijzigd door Sjaaky op 13-05-2004 14:32 ]


Verwijderd

Topicstarter
djluc schreef op 13 mei 2004 @ 14:20:
[...]
Heb je ook al het geheugengebruik werkelijk gemeten? Heb je dus wel echt te weinig geheugen of heb je een te kleine swap file o.i.d.?
Zopas eens gekeken voor een andere pc. Specs: P4 2,4Ghz, 256MB RAM, Win2K.
Daar wilt het programma perfect werken. Het laden van het gecompileerd project (dat nu enkel bestaat uit 1 form met bovenstaande code) duurt vrij lang (5 seconden), de cpu-load bedraagt dan 45%. Na het laden verschijnt de form en neemt het programma 8655KB in beslag (8MB).

Teveel resources dus :(
Sjaaky schreef op 13 mei 2004 @ 14:22:

code:
1
2
3
PictureWit = LoadPicture(Padnaam & "\wit.bmp")
PictureRood = LoadPicture(Padnaam & "\rood.bmp")
...
Ik heb problemen om Picturewit te declaren. Hoe moet ik ze declareren?
dim Picturewit as object lukt niet.

  • GigaDave56
  • Registratie: Juni 2001
  • Laatst online: 14-12-2025
Verwijderd schreef op 13 mei 2004 @ 14:51:
[...]
Ik heb problemen om Picturewit te declaren. Hoe moet ik ze declareren?
dim Picturewit as object lukt niet.
Loadpicture wordt gebruikt als volgt.
Form.Picture1.Picture = LoadPicture(<path>) of Form.Image1.Picture = LoadPicture(<path>)

Wat Sjaaky eigenlijk bedoelt, denk ik, is het volgende:
Je neemt 2 pictureboxen en geeft de eerste als picture wit.jpg en de tweede rood.jpg. Daarna loop je je matrix af en geeft voor elk punt op ImgPixel(I).picture = form1.picture1.picture (wit) of form1.picture2.picture (rood). Door te refereren aan die eerste twee pictureboxen, scheelt je geheugengebruik.

Not so Giga One
> I'd sell my soul for you, babe
> For money to burn, for you
> I'd give you all and have none, babe
> Just to, just to, to have you here by me... [Scooter - Rebel yell]


  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 22-05 22:34

Gerco

Professional Newbie

Je kan PictureWit en PictureRood ook declaren als StdPicture, dan hoef je geen PictureBox te gebruiken, scheelt weer een (klein) beetje geheugen.
Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Dim PicWit  As StdPicture
Dim PicRood As StdPicture

PictWit  = LoadPicture(Padnaam & "\wit.bmp")
PictRood = LoadPicture(Padnaam & "\rood.bmp")

For y = 1 To veel
    For x = 1 To veel
        Load imgPixel(i)
        If i = wit Then
            Set imgPixel(i).Picture = PicWit
        Else
            Set imgPixel(i).Picture = PicRood
        End If
    Next x
Next y

[ Voor 11% gewijzigd door Gerco op 13-05-2004 15:20 ]

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


Verwijderd

Topicstarter
Er zitten hier toch echte kenners hé _/-\o_ _/-\o_
Heb dus 2 images (image1 en image2 bijgezet).

image1 = geladen met rood.bmp
image2 = geladen met wit.bmp

huidige code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
For Y = 1 To Hoogte - 1
        For X = 1 To Breedte - 1


            imgPixel(I).Visible = True
                
                If KarakterSet(I) = True Then 'true = 0 = lamp brandt
                    imgPixel(I).Picture = Image2.Picture
                Else
                    imgPixel(I).Picture = Image1.Picture
                End If
            imgPixel(I).Visible = True
            imgPixel(I).Left = X * 250 + (X - 1) * imgPixel(1).Width
            imgPixel(I).Top = Y * 250 + (Y - 1) * imgPixel(1).Top
            imgPixel(I).Refresh
            I = I + 1

        Next X
Next Y


Gevolg:
op de Win2K pc: laden gebeurt direct (orde milliseconden); geheugenverbruik van 8MB naar 2200KB :)

Op mijn PC (PIII 550, 256MB) laadt het nu ook vlot zonder te crashen.


Thx a lot voor jullie reacties :)

Verwijderd

Topicstarter
Ik krijg bij jouw code: "invalid use of property" Ik heb wel pictwit verandert naar picwit.

debugger arceert: "PicWit = LoadPicture(PadNaam & "\wit.bmp")"

[ Voor 18% gewijzigd door Verwijderd op 13-05-2004 15:27 ]


  • GigaDave56
  • Registratie: Juni 2001
  • Laatst online: 14-12-2025
Verwijderd schreef op 13 mei 2004 @ 15:26:
[...]


Ik krijg bij jouw code: "invalid use of property" Ik heb wel pictwit verandert naar picwit.

debugger arceert: "PicWit = LoadPicture(PadNaam & "\wit.bmp")"
Volgens mij moet het: PicWit.picture = LoadPicture(PadNaam & "\wit.bmp")

edit:
Wacht even, picture is toch de default property... dan klopt mijn opmerking niet :Z

[ Voor 19% gewijzigd door GigaDave56 op 13-05-2004 15:34 ]

Not so Giga One
> I'd sell my soul for you, babe
> For money to burn, for you
> I'd give you all and have none, babe
> Just to, just to, to have you here by me... [Scooter - Rebel yell]


  • Mart!
  • Registratie: Februari 2000
  • Laatst online: 15:37
ik zou helemaal geen picturebox gebruiken, gewoon een label, en deze geeff je de correcte achtergrondkleur. Werkt zeker beter dan een image control, want VEEL minder geheugen

label.BackColor = vbRed
label.BackColor = vbWhite

[ Voor 7% gewijzigd door Mart! op 13-05-2004 17:29 ]


  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Verwijderd schreef op 13 mei 2004 @ 15:26:
[...]


Ik krijg bij jouw code: "invalid use of property" Ik heb wel pictwit verandert naar picwit.

debugger arceert: "PicWit = LoadPicture(PadNaam & "\wit.bmp")"
Objecten moet je met Set aanroepen. Dus:
Visual Basic:
1
Set PicWit = LoadPicture(PadNaam & "\wit.bmp")

  • Stamgastje
  • Registratie: April 2003
  • Laatst online: 02-02-2020
Mart! schreef op 13 mei 2004 @ 17:29:
ik zou helemaal geen picturebox gebruiken, gewoon een label, en deze geeff je de correcte achtergrondkleur. Werkt zeker beter dan een image control, want VEEL minder geheugen
En ik zou helemaal geen aparte control per "ledje" gebruiken... echt onzinnig veel geheugengebruik!!!

Edit: zie code in de post hieronder.

[ Voor 64% gewijzigd door Stamgastje op 13-05-2004 18:17 ]


  • Stamgastje
  • Registratie: April 2003
  • Laatst online: 02-02-2020
Oke, je hebt geluk: ik zoek afleiding tussen het leren voor mijn tentamen door :)

Bij deze volledige 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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Option Explicit

Private Const w = 80, h = 16
Private Led(1 To w, 1 To h) As Boolean

Private Sub Command1_Click()

    Dim i As Integer, j As Integer
    Dim r As Single, c As Long
    
    Picture1.AutoRedraw = True
    Picture1.ScaleWidth = w
    Picture1.ScaleHeight = h
    Picture1.Cls
    Picture1.FillStyle = vbFSSolid
    
    Randomize Timer
    
    For j = 1 To h
        For i = 1 To w
            If Rnd < 0.5 Then
                c = RGB(255, 0, 0)
                Led(i, j) = 0
            Else
                c = RGB(255, 255, 255)
                Led(i, j) = 1
            End If
            Picture1.FillColor = c
            Picture1.ForeColor = c
            Picture1.Circle ((i - 0.5), (j - 0.5)), 0.5
        Next
    Next
    
    Picture1.AutoRedraw = False

End Sub

Private Sub Form_Load()

    Call Command1_Click

End Sub

Private Sub Picture1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)

    Dim xp As Integer, yp As Integer
    Dim c As Long

    If (Button <> vbLeftButton) Or (Shift <> 0) Then Exit Sub
    
    xp = Int(X) + 1: yp = Int(Y) + 1
    
    Picture1.AutoRedraw = True
    
    If Led(xp, yp) = 0 Then
        c = RGB(255, 255, 255)
        Led(xp, yp) = 1
    Else
        c = RGB(255, 0, 0)
        Led(xp, yp) = 0
    End If
    Picture1.FillColor = c
    Picture1.ForeColor = c
    Picture1.Circle ((xp - 0.5), (yp - 0.5)), 0.5
    
    Picture1.AutoRedraw = False

End Sub


Zorg er wel voor dat je picturebox groot genoeg is (bijv. 8000 breed, 1600 hoog). Succes ermee!

De code kun je ook hier even downloaden.

[ Voor 202% gewijzigd door Stamgastje op 13-05-2004 18:16 ]


Verwijderd

Topicstarter
Prachtig alternatief dat nog minder resources vraagt. Ik overweeg over te stappen naar deze methode van jou.

Maar hoe zou ik moeten de gebruiker laten inzoomen in zo'n picturebox? De pixels zouden ook moeten vergroten.

  • Stamgastje
  • Registratie: April 2003
  • Laatst online: 02-02-2020
Ik zal eens kijken of ik toevallig vanavond wat tijd over heb om dat in elkaar te knutselen...

PS: Misschien is het een idee om ook meteen naar Delphi o.i.d. over te stappen? Is weer wat sneller dan VB en je bent ook niet meer afhankelijk van alle runtime libraries van VB. De code ziet er trouwens in Delphi redelijk vergelijkbaar uit.

[ Voor 57% gewijzigd door Stamgastje op 16-05-2004 13:18 ]


Verwijderd

Topicstarter
Een eerste en laatste upje. Misschien komen er nog goede ideeën als er andere users deze thread lezen.
Pagina: 1