Results 1 to 12 of 12

Thread: Out of memory somewhat reproducable

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    760

    Question Out of memory somewhat reproducable

    My app is huge with several hundred thousand lines of code.

    From time to time I get the error "Out of memory".

    I have been able to somewhat reproduce it.
    I have uploaded a video here:

    https://youtu.be/iIZT-WisctY

    If anybody has any idea what I could check, please let me know.

    Thank you!

    Edit: Updated video link as YT for some reason blocked it.
    Last edited by tmighty2; Feb 3rd, 2024 at 05:23 PM.

  2. #2
    Fanatic Member
    Join Date
    Apr 2021
    Posts
    616

    Re: Out of memory somewhat reproducable

    Quote Originally Posted by tmighty2 View Post
    My app is huge with several hundred thousand lines of code.
    Could it be that, perchance?

    Does 100% of the code need to be in the app, or can some of it be put into DLLs to be called from the main app on-demand?

    VB6 has a limited amount of memory space available, being a 32-bit system, and you need to be creative and strict about your variables to keep them and the code within that limitation

  3. #3
    Addicted Member
    Join Date
    May 2012
    Location
    42.787034,-81.176367
    Posts
    197

    Re: Out of memory somewhat reproducable

    Not the best solution, but you could make the VB6 IDE /LARGEADDRESSAWARE by using EDITBIN.EXE

    You could also make your compiled .EXE LargeAddressAware by adding;
    Code:
    [VBCompiler]
    LinkSwitches=/LARGEADDRESSAWARE
    ...to your projects .VBP file.

    Out of Memory - Ref: https://www.vbforums.com/showthread....=1#post5626457

    LARGEADDRESSAWARE - Ref: https://www.vbforums.com/showthread....=1#post5626457

    Joe

  4. #4
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,909

    Re: Out of memory somewhat reproducable

    Personally, I think you should be looking at data you're reading into memory. You'd be very surprised at how tightly VB6 code compiles into machine language. But large arrays (Collections, Dictionaries, etc) can easily blow up memory.

    Also, just other thoughts, be sure you actually are compiling to machine code, and not p-code.

    Does your program compile and run in the IDE? If so, that's more evidence that it's not the amount of code you have, as it'll take much more memory to run in the IDE than it would take as a machine code compiled EXE. When loading/running in the IDE, you're still limited to 2GB, including the IDE itself, and all the compiled p-code (which is what it is) when you execute from the IDE.

    Another thought is that it might be some kind of recursion-gone-wild problem, but I believe that always reports an "out of stack space" error.

    Also, it's possible you're doing some kind of memory manipulation with APIs, and not doing it correctly. That could also easily blow up your memory.

    ------------

    Regarding LAA, I'm not a fan. I know that a couple of people here use it, but any piece of code (your memory pointer code, third-party OCXs or DLLs) that don't correctly handle memory pointers, could hard-crash your program with LAA.

    The "shuttle code to ActiveX DLLs" is a good idea, but, if you do that, you need to make sure there are chunks of code that you can load, and then unload when done, for that to be useful. If all of your code needs to be in memory at the same time, then ActiveX DLLs will actually be a hindrance.

    ------------

    p.s. My primary application is also 100s of 1000s of lines of code, and I've got no memory problems at all. However, for the primary data storage, I use an MDB database, and the DAO to manipulate it. I'll occasionally have 20 or more tables open, but seldom will I actually read much data into memory. During various processing, I might read large ASCII files into memory in their entirety, but an ASCII file would have to be really large to make much of a dent on 2GB.

    Just as a further FYI, on a 64-bit Windows machine (which most everything is these days) with any decent amount of memory in it (say, 8GB or more), we do get a full 2GB of memory for our VB6 program.
    Last edited by Elroy; Feb 3rd, 2024 at 09:09 AM.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  5. #5
    PowerPoster
    Join Date
    Feb 2017
    Posts
    5,666

    Re: Out of memory somewhat reproducable

    Quote Originally Posted by tmighty2 View Post
    Name:  YT_VBF.jpg
Views: 414
Size:  14.2 KB

    This video is no longer available because the account was closed.
    What's going on, tmighty2?

  6. #6

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    760

    Re: Out of memory somewhat reproducable

    Thank you for the hint.

    Not sure why that happened.

    Here is a new link:

    https://youtu.be/iIZT-WisctY

  7. #7
    PowerPoster Arnoutdv's Avatar
    Join Date
    Oct 2013
    Posts
    6,733

    Re: Out of memory somewhat reproducable

    You have an out of memory in the IDE, wow
    When you open the task manager, how much memory does VB6 use?
    How large are your modules? I believe there is a maximum for the number of characters a single module can have.
    Do you get the same Out of memory error when you edit the code without having started the project first?

    How much memory is used by VB6 when you only open your project?
    How memory is used when the project is started?
    How much memory is used when you return to the IDE?

  8. #8

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    760

    Re: Out of memory somewhat reproducable

    Name:  vb61.jpg
Views: 487
Size:  3.3 KB

    79.4 MB when I open up the project in VB6.

    350 MB when I run the app in the IDE.

    Name:  stats0.jpg
Views: 418
Size:  20.8 KB

    Name:  ctls1.jpg
Views: 411
Size:  20.1 KB
    Last edited by tmighty2; Feb 3rd, 2024 at 05:47 PM.

  9. #9
    PowerPoster
    Join Date
    Feb 2017
    Posts
    5,666

    Re: Out of memory somewhat reproducable

    That generic "out of memory" VB6 error is a bit misleading because it encompasses many limited resources that are not literally "memory". And sometimes limited by a registry setting and not the actual hardware.

  10. #10

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    760

    Re: Out of memory somewhat reproducable

    I have removed the reference to msxml6.dll and use CreateObject, and the error is gone.

    I have readded it, and so far, the error is still gone.

    If anybody has any idea how to debug this, please tell me.

  11. #11
    PowerPoster Arnoutdv's Avatar
    Join Date
    Oct 2013
    Posts
    6,733

    Re: Out of memory somewhat reproducable

    Quote Originally Posted by tmighty2 View Post
    I have removed the reference to msxml6.dll and use CreateObject, and the error is gone.

    I have readded it, and so far, the error is still gone.

    If anybody has any idea how to debug this, please tell me.
    The error you get in the Youtube clip is a VB6 IDE error, how do you want to debug the IDE itself

  12. #12

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    760

    Re: Out of memory somewhat reproducable

    The first thing I always notice that is VB6 does is to jump to a line using something like this:

    Code:
    Dim s$
    s = Command() ' IDE jumps here with "Out of memory"
    It usually happens with functions like:

    Code:
    = Hex(
    Code:
    = Left(
    Code:
    = ChrW(
    I noticed I kept mixing up the $ vs. non-$ variants of string functions. I thought this might cause headaches for the compiler, so I tried to always use the correct $ variant. But even after fixing them many times, I would keep slipping back into using the wrong one when writing new code.

    To reduce mistakes (and see if it could help avoid Out of memory), I added safeguards: I block the unsafe calls and force myself to use wrapper functions with a …2 suffix instead. Example:

    Code:
    Public Function Left2(ByVal uString As String, ByVal uLength As Long) As String
    Left2 = VBA.Left$(uString, uLength)
    End Function
    
    Public Sub Left()
    ' safeguard: prevent direct use, must call Left2()
    Debug.Assert False
    End Sub
    With TwinBasic I can now also locate lines that VB6 could not show before due to "Out of memory", for example:

    Code:
    u = Replace(u, ChrW$(34), "")
    So I expanded this safeguard approach to many functions — each blocked with a Sub, plus a corresponding wrapper function that always calls the $ variant. For example:
    Code:
    Public Function Left2(ByVal uString As String, ByVal uLength As Long) As String
    Left2 = VBA.Left$(uString, uLength)
    End Function
    
    Public Sub Left()
    ' safeguard: prevent direct use, must call Left2()
    Debug.Assert False
    End Sub
    So I expanded this safeguard approach to many functions — each blocked with a Sub, plus a corresponding wrapper function that always calls the $ variant. For example:

    Code:
    Public Sub ChrW()
    ' safeguard: must use ChrW2()
    Debug.Assert False
    End Sub
    
    Public Function ChrW2(ByVal CharCode As Long) As String
    ChrW2 = VBA.ChrW$(CharCode)
    End Function
    
    Public Sub Command()
    ' safeguard: must use Command2()
    Debug.Assert False
    End Sub
    
    Public Function Command2() As String
    Command2 = VBA.Command$()
    End Function
    
    Public Sub CurDir()
    ' safeguard: must use CurDir2()
    Debug.Assert False
    End Sub
    
    Public Function CurDir2(Optional Drive As String) As String
    CurDir2 = VBA.CurDir$(Drive)
    End Function
    
    Public Sub Dir()
    ' safeguard: must use Dir2()
    Debug.Assert False
    End Sub
    
    Public Function Dir2(Optional Pathname As String, Optional Attributes As VbFileAttribute = vbNormal) As String
    Dir2 = VBA.Dir$(Pathname, Attributes)
    End Function
    
    Public Sub Environ()
    ' safeguard: must use Environ2()
    Debug.Assert False
    End Sub
    
    Public Function Environ2(ByVal Name As String) As String
    Environ2 = VBA.Environ$(Name)
    End Function
    
    Public Sub Format()
    ' safeguard: must use Format2()
    Debug.Assert False
    End Sub
    
    Public Function Format2(ByVal Expression As Variant, Optional ByVal Style As String) As String
    Format2 = VBA.Format$(Expression, Style)
    End Function
    
    Public Sub FormatCurrency()
    ' safeguard: must use FormatCurrency2()
    Debug.Assert False
    End Sub
    
    Public Function FormatCurrency2(ByVal Expression As Variant, Optional NumDigitsAfterDecimal As Integer = -1, Optional IncludeLeadingDigit As VbTriState = vbUseDefault, Optional UseParensForNegativeNumbers As VbTriState = vbUseDefault, Optional GroupDigits As VbTriState = vbUseDefault) As String
    FormatCurrency2 = VBA.FormatCurrency$(Expression, NumDigitsAfterDecimal, IncludeLeadingDigit, UseParensForNegativeNumbers, GroupDigits)
    End Function
    
    Public Sub Hex()
    ' safeguard: must use Hex2()
    Debug.Assert False
    End Sub
    
    Public Function Hex2(ByVal Number As Variant) As String
    Hex2 = VBA.Hex$(Number)
    End Function
    
    Public Sub LCase()
    ' safeguard: must use LCase2()
    Debug.Assert False
    End Sub
    
    Public Function LCase2(ByVal uString As String) As String
    LCase2 = VBA.LCase$(uString)
    End Function
    
    Public Sub Left()
    ' safeguard: must use Left2()
    Debug.Assert False
    End Sub
    
    Public Function Left2(ByVal uString As String, ByVal uLength As Long) As String
    Left2 = VBA.Left$(uString, uLength)
    End Function
    
    Public Sub Mid()
    ' safeguard: must use Mid2()
    Debug.Assert False
    End Sub
    
    Public Function Mid2(ByVal uString As String, ByVal uStart As Long, Optional ByVal uLength As Long) As String
    Mid2 = VBA.Mid$(uString, uStart, uLength)
    End Function
    
    Public Sub Right()
    ' safeguard: must use Right2()
    Debug.Assert False
    End Sub
    
    Public Function Right2(ByVal uString As String, ByVal uLength As Long) As String
    Right2 = VBA.Right$(uString, uLength)
    End Function
    
    Public Sub Trim()
    ' safeguard: must use Trim2()
    Debug.Assert False
    End Sub
    
    Public Function Trim2(ByVal uString As String) As String
    Trim2 = VBA.Trim$(uString)
    End Function
    
    Public Sub UCase()
    ' safeguard: must use UCase2()
    Debug.Assert False
    End Sub
    
    Public Function UCase2(ByVal uString As String) As String
    UCase2 = VBA.UCase$(uString)
    End Function
    
    Public Sub RTrim()
    ' safeguard: must use RTrim2()
    Debug.Assert False
    End Sub
    
    Public Function RTrim2(ByVal uString As String) As String
    RTrim2 = VBA.RTrim$(uString)
    End Function
    
    Public Sub LTrim()
    ' safeguard: must use LTrim2()
    Debug.Assert False
    End Sub
    
    Public Function LTrim2(ByVal uString As String) As String
    LTrim2 = VBA.LTrim$(uString)
    End Function
    
    Public Sub Space()
    ' safeguard: must use Space2()
    Debug.Assert False
    End Sub
    
    Public Function Space2(ByVal Number As Long) As String
    Space2 = VBA.Space$(Number)
    End Function
    
    Public Sub Str()
    ' safeguard: must use Str2()
    Debug.Assert False
    End Sub
    
    Public Function Str2(ByVal Number As Variant) As String
    Str2 = VBA.Str$(Number)
    End Function
    
    Public Function String2(ByVal Number As Long, ByVal Character As Variant) As String
    String2 = VBA.String$(Number, Character)
    End Function
    
    Public Function Chr2(ByVal CharCode As Long) As String
    Chr2 = VBA.Chr$(CharCode)
    End Function
    A few functions (Input$, String$) can’t be safeguarded this way because their names cause conflicts.

    If VB6 would not even jump to a specific line but would simply say "Out of memory", I would use TwinBasic.

    TwinBasic would then show me a line like this:


    With TwinBasic I can now also locate lines that VB6 could not show before due to "Out of memory", for example:

    Code:
    u = Replace(u, ChrW$(34), "")
    That line would be not compilable because of the safeguard for ChrW().

    Whether these safeguards completely prevent the "Out of memory" issue is unclear, but since that is I thing that the compiler jumps to at first, I had to tackle it.
    Last edited by tmighty2; Oct 11th, 2025 at 09:32 AM.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width