VB6 is a full blown 32 bit application. That means that all of its internal memory pointers are unsigned 32 bit (4 byte) integers. That means that it's capable of addressing 4gig of address space. Some will argue that it starts complaining at about 2.5gig, but that's not my experience on a machine with plenty of memory.
Because of the way these pointers are handled, any particular dynamic string or array is limited to 2 gig. One of the most restrictive limits is the way User Defined Types (UDTs, or structures) are handled. This restriction also applies to fixed length strings (but not variable length strings). The static portion of UDTs or fixed length strings is 64k. However, you can have as many of these as you like in a single program.
I have no idea where the 80meg number is coming from. Bottom line, as a high-level 32 bit language, VB6 absolutely runs with the best of them.
EDIT: Also, don't forget that classes (for the creation of object) is fully implemented in VB6. In fact, this same technology is used for creating forms. What this means is that the code and user interfaces in the EXE is seldom (if ever) completely pulled into memory. The typical EXE for a primary application that I distribute is 95meg, and I can promise that, at times, it pulls VERY LARGE chunks of data into memory for various reasons, and, if I dare say, this application runs flawlessly.
Last edited by Elroy; Nov 5th, 2014 at 09:36 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.
I'd love to see some documentation regarding your claim. I understand that, under normal operations that a Long is treated (mathematically) as a signed 4 byte integer. However, when used as an internal pointer to memory addresses, there's no need to concern ourselves with the sign bit. Also, although it's easy to get a pointer into a long, they're not quite the same thing. In many circumstances, a Long is used for MANY things other than a pointer. Also, a pointer is relatively internal to VB6's operations and not often explicitly utilized in VB6 coding.
I've seen in many write-ups that VB6 can address 4gig of memory space, but I'll admit I've never actually performed a test. Here's a reference I found without doing an extensive search: "In a 32-bit operating system (for example, Win 95 and Win NT), the size of the pointer is 32 bits (4 bytes) and has a range of 0 to 4,294,967,296 (approx 4 Gigs)" found in:
I'm certainly willing to stand corrected, but I'd sure like to see some VB6 documentation from Microsoft that explicitly states that the sign bit can't be used on internal address pointers.
Regards,
Elroy
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.
32-bit applications can only access 2GB of memory. This is a limitation imposed by Windows, and it exists regardless of programming language, available RAM, or pagefile size. Previous vbForums conversation on this topic:
As that link discusses, there is a workaround to enable 3GB instead of 2GB on 32-bit versions of Windows, and the full 4GB on 64-bit versions, but I have never found evidence of a VB developer using IMAGE_FILE_LARGE_ADDRESS_AWARE successfully (though I would love to be proved wrong).
Actually, I can only get about .5 gig allocated. My machine has 8 gig in it. However, I haven't rebooted it in quite a while and it may be struggling to find contiguous memory. I would hope that that would clean itself up. I did it a couple different ways:
Code:
Option Explicit
Private Sub Form_Load()
Dim d1(1 To 33554432) As Double ' 256 meg each, or .25 gig.
Dim d2(1 To 33554432) As Double
Dim d3(1 To 33554432) As Double ' <----- it fails with "out of memory" when this line is included.
End Sub
or
Code:
Option Explicit
Private Sub Form_Load()
Call a1
End Sub
Sub a1()
Dim d(1 To 33554432) As Double ' 256 meg each, or .25 gig.
Call a2
End Sub
Sub a2()
Dim d(1 To 33554432) As Double ' 256 meg each, or .25 gig.
Call a3 ' <--- it fails trying to make this call, which is when a3 is going to try and dim.
End Sub
Sub a3()
Dim d(1 To 33554432) As Double ' 256 meg each, or .25 gig.
End Sub
In any event certainly FAR more than 80 meg. Under certain circumstances though, it does seem that 512 meg might be a limit. Until otherwise proven, I am going to believe that that's a limit of ANY 32 bit application (other than the IMAGE_FILE_LARGE_ADDRESS_AWARE), and not peculiar to VB6.
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.
I should have mentioned that the test was from a compiled .exe on a freshly booted computer. The IDE will run out of memory much faster of course.
Also, the test allocates quite large chunks of memory, but not necessarily in one that is the mother of all arrays. But the count, if I have my maths right, is still very real.
Firefox and most media players are very good at fragmenting memory, memory leaks and all sort of things. My cad/drawing/photo-editing program handles very large amount of data, sometimes it runs out after computer has used Web or Media. Re-booting brings back to normal.
On win10 (2 gig system) on a freshly booted computer, I can handle pictures up to 250 megapixels, with double buffering. A bit touchy at this size, but still.
Hmmm, yeah, I got to about 1.5 gig after compiling. And good point about needing to get out-from-under the IDE.
Here's the code I used:
Code:
Option Explicit
Private Sub Form_Load()
Call a1
End Sub
Sub a1()
Dim d(1 To 67108864) As Double ' 512 meg each, or .5 gig.
MsgBox "made it to a1"
Call a2
End Sub
Sub a2()
Dim d(1 To 67108864) As Double ' 512 meg each, or .5 gig.
MsgBox "made it to a2"
Call a3
End Sub
Sub a3()
Dim d(1 To 67108864) As Double ' 512 meg each, or .5 gig.
MsgBox "made it to a3"
Call a4 ' <------ Crashed here when compiled.
End Sub
Sub a4()
Dim d(1 To 33554432) As Double ' 256 meg each, or .25 gig.
MsgBox "made it to a4"
Call a5
End Sub
Sub a5()
Dim d(1 To 33554432) As Double ' 256 meg each, or .25 gig.
MsgBox "made it to a5"
End Sub
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.
Guys, also please have a look at http://ntcore.com/4gb_patch.php. On a 64bit OS, this will allow running VB executables to access > 2 GB memory. The utility provided there just patches a flag in the PE header of the exe file, it's that easy :-)
Just adding my 2 cents. Modifiying the PE IMAGE_FILE_HEADER.Characteristics by adding (ORring really) with IMAGE_FILE_LARGE_ADDRESS_AWARE does allow a compiled VB6 Executable to allocate ~ 3.8GB on Windows x64.
I haven't tried modifying the VB6 IDE yet, to see if this works during debugging as well.
a post build step can also be added that runs:
Code:
LINK.EXE /EDIT /LARGEADDRESSAWARE Filename.exe
Last edited by DEXWERX; Aug 20th, 2015 at 09:26 AM.
I have collected a similar patch some time ago. I think it may have been .exe only, anyway, end result is I never actually tried it.
But thank you for this, i could not resist trying it from source code. Worked like a charm on a 64 bits Win 8.
What's with Win10? the casual reader may ask.
Well, after running the Win10 TP up until may (when I moved) and after considering where MS, Windows 10 and Visual Studio is leading us, the computer I used for Win10 is now running a Linux Mint distro. Gotta be ready for the after VB6 era at one point or another and for me, that ain't .Net
Nice. I tend to diversify myself. Lot's of VMs. I still prefer VB6 Apps but keep most of the API's I use to mimic .NET syntax using my own custom classes as well as vbCorLib.dll. Just in case someone someday has the hard luck of converting the code to .NET. So far now though it looks like VB Classic will never die.
Well, after running the Win10 TP up until may (when I moved) and after considering where MS, Windows 10 and Visual Studio is leading us, the computer I used for Win10 is now running a Linux Mint distro. Gotta be ready for the after VB6 era at one point or another and for me, that ain't .Net
Modifiying the PE IMAGE_FILE_HEADER.Characteristics by adding (ORring really) with IMAGE_FILE_LARGE_ADDRESS_AWARE does allow a compiled VB6 Executable to allocate ~ 3.8GB on Windows x64.
. . .
a post build step can also be added that runs:
Yet another way of setting the /LARGEADDRESSAWARE flag is by exploiting the undocumented [VBCompiler] option for .VBP files:
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
Thanks Bonnie, for that and for all the other bits of knowledge you are blessing VB Forums with.
Now from there and a quick google search , it is quite simple to jump virtual memory addressing to 3 gig on Vista 32 bits (and I would assume for Win7,8,10 32 bits version)
All that is required is this, typed in an administrative command prompt (and reboot)
On a side note, while Bonnie's solution is by far much simpler, it does not render DEXWERX solution useless since it can be applied on your already compiled body of work.
What is the effect of the /LARGEADDRESSAWARE switch on a DLL?
Nothing. Large-address-awareness is a process property, which comes from the EXE.
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
OK. Noted.
I put the switch in both ActiveX project and demo project,then I created a very large 2D array, w/o or with this switch, there's no effect. Still crash.
I may follow up when I make more test.
Last edited by Jonney; Jan 25th, 2016 at 08:02 PM.