Last Update: 2021 - 12- 18
The /LARGEADDRESSAWARE (LAA) flag demystified
by Philipp Stiefel, originally published 2020-11-30, last updated 2020-11-30
At the Access developer conference AEK2019 Björn Fox presented a very interesting approach to resolve out of memory and system resources exceeded error messages in 32bit Microsoft Access. These errors may happen if your Access application has complex forms, e.g. a main form with many sub forms or when your application allows the user to open many forms at the same time.
His approach was to set the /LARGEADDRESSAWARE (LAA) flag for the MsAccess.exe. – Now, almost a year later, this has proven to be very helpful to me.
What is LAA about?
To understand what this means we need to go back in time. When the Windows operating system was 32bit only, it was able to address a maximum of 4GB of RAM memory (theoretically, effectively only ~3GB). Any application instance running on 32bit Windows was only allowed a maximum of 2GB of memory. The remaining memory was reserved for the operating system to run its own processes and other applications.
This made sense with the restrictions of a 32bit operating system. When running a 32bit application on a 64bit operating system this is an artificial limitation. From the operating systems perspective, it is easily possible to assign 4GB of memory to a 32bit process.
The Risk with LAA
Still, there is a reason to keep the 2GB limitation for 32bit applications. When using Int32 pointers to address memory, these pointers become negative when they point to memory above the 2GB threshold. As this is something that simply cannot happen on 32bit Windows, there are 32bit applications that cannot handle this situation and will not function correctly then.
This is why the /LARGEADDRESSAWARE flag was introduced into the Portable Executable (PE) file format header. The LAA flag indicates to the operating system that this 32bit application is “certified” by its developers to handle full 4GB of memory.
The LAA flag was set for several Microsoft Office applications (e.g. Outlook and Excel) in recent years, but not for Microsoft Access yet. So regardless how much physical memory your computer has, the MsAccess.exe is still limited to 2GB. I don’t know the reason for that, but there is one thing to consider with /LAA. This does not only affect the main application, but also all DLL libraries and ActiveX controls that are loaded into that process. Maybe the Microsoft Access developer team at Microsoft considered the risk of setting the flag for Access bigger than for Outlook and Excel due to more 3rd party components being used in Access.
Finally, in May 2020 Microsoft agreed to also make Access large address aware. But this change is not yet rolled out (as of November 2020) and it will most likely only be applied to Access 2016/365 and future versions, but not to older versions.
Do it yourself LAA – Words of Warning
The LAA flag is a fully documented setting the in the header of PE files (all Windows .exes). So, it is possible for anyone to set this flag for any .exe file on their own computer. However, you should not do that blindly, but verify that the application in question actually works with the LAA lag set. This is not as easy as it sounds, there are potential issues with setting LAA and testing for them.
Microsoft Access itself and the standard libraries supplied by Microsoft can be considered safe for the LAA flag. But we as Access developers also need to verify that any 3rd party library we and our customers use, is safely working with a large address space.
Do it yourself LAA – How to do it
Before we get started, keep in mind, you need Administrator permissions to modify a file in the Program Files directories of your computer.
Also keep in mind, any update to the .exe file you modified will not include the modification and thus reset the LAA flag. If this happens you need to reapply the LAA patch.
Ok, with that out of the way, let’s look at how to actually apply the LAA flag.
If you consider applying the LAA flag to any executable, I strongly advise to make a backup copy of the .exe file before modifying the file!
Apply /LAA using Visual C++ editbin
If you have Visual C++ installed, this is quite easy. You can use the editbin command line utility to set the LAA flag. The command line looks like this:
"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\editbin.exe" /LARGEADDRESSAWARE "C:\Program Files (x86)\Microsoft Office 2007\Office12\MSACCESS.EXE" (put all on one line)
editbin does not explicitly report success. If it completes execution without error, you can assume it worked. You can verify that it actually worked using the dumpbin utility with the /HEADERS switch.
"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\dumpbin.exe" /HEADERS "C:\Program Files (x86)\Microsoft Office 2007\Office12\MSACCESS.EXE" (put all on one line)
Apply /LAA using VBA
The above solution using editbin is easy, but most computers do not have an installation of Visual C++ available. What then?
There is a free tool (“Large Address Aware.exe”) available from someone in the gamer community to set the /LAA flag to an exe file. But…
Have you ever had that conversation with the responsible sysadmin: “Download that tool from a dodgy source and then run it with admin privileges to muck with your program files!”? – I can tell how that will go down…, but I won’t. Try for yourself. ;-)
I currently have a client whose Access application is suffering severely from an out-of-memory situation. I wanted to employ the /LARGEADDRESSAWARE flag to remedy the problem. So, I decided to create my own solution to set and optionally unset the LAA flag for MsAccess.exe.
I do not assume that I’m inherently more trustworthy than any other random guy on the internet to your sysadmin. However, my implementation is in plain VBA, enabling you (and your sysadmin) to read the full code and hopefully understand it to the point to be sure it doesn’t do any malicious mischief.
Do not just copy and paste the below procedure! It depends on some supporting code left out here for brevity. Instead download the complete module modLargeAddressAware containing all required code.
Here is the core function of my implementation:
Public Sub SetLaaFlag(ByVal ExeFileName As String, ByVal operationMode As LaaMode) Dim fileStream As Object Set fileStream = CreateObject("ADODB.Stream") fileStream.Type = adTypeBinary fileStream.Mode = adModeReadWrite fileStream.Open fileStream.LoadFromFile ExeFileName Dim LaaPosition As Integer LaaPosition = GetLaaPosition(fileStream) ' reading the byte with the LAA-Flag Dim readBuffer() As Byte fileStream.Position = LaaPosition readBuffer = fileStream.Read(1) ' Check if LAA flag set Dim LaaIsEnabled As Boolean LaaIsEnabled = CBool((readBuffer(0) And EXE_FILE_LARGE_ADDRESS_AWARE) = EXE_FILE_LARGE_ADDRESS_AWARE) Debug.Print "LAA is " & IIf(LaaIsEnabled, "", "NOT ") & "enabled." If Not operationMode = DisplayLaaStatusOnly Then Dim writeBuffer(0) As Byte Dim doWrite As Boolean ' Applying the desired LAA flag value If LaaIsEnabled _ And operationMode = TurnOffLaa _ Then writeBuffer(0) = (readBuffer(0) Xor EXE_FILE_LARGE_ADDRESS_AWARE) doWrite = True ElseIf Not LaaIsEnabled _ And operationMode = TurnOnLaa _ Then writeBuffer(0) = (readBuffer(0) Or EXE_FILE_LARGE_ADDRESS_AWARE) doWrite = True Else Debug.Print "Doing nothing" End If If doWrite Then Debug.Print "Switching "; IIf(operationMode = TurnOnLaa, "ON", "OFF") & " LAA" ' Writing LAA byte to stream fileStream.Position = LaaPosition fileStream.Write writeBuffer ' Saving stream to disk fileStream.SaveToFile ExeFileName, adSaveCreateOverWrite Debug.Print "Success - Updated file was written to disc" End If End If fileStream.Close End Sub
If you want to enable the LAA-Flag in Microsoft Access or any other .exe-application, here’s what you should do:
Download the module modLargeAddressAware and extract it from its ZIP archive. Then open the VBA editor in any VBA enable application, like Word or Excel. Then import the module file using “File” – “Import File” to load the module into the VBA project.
Keep in mind:
In the VBA Editor you can then call the SetLaaFlag procedure from the Immediate Pane to either view, set, or unset the LAA flag. Here is an example for turning it on for Access 2007:
SetLaaFlag "C:\Program Files (x86)\Microsoft Office 2007\Office12\MSAccess.exe", TurnOnLaa
In my code I used an ADODB.Stream to read and write to the .exe binary file. I did this with the intention to port the code to a VBScript to make it independent of any VBA enabled application. However, that proved to be a tough nut because that [expletives censored] VBScript interpreter is not able to handle the byte array read from the stream correctly.
It is not always possible to reduce the memory consumption of your Access application by simplifying forms, reducing the number of open forms, or implementing lazy loading of sub forms and/or data. If these approaches are not feasible, the /LARGEADDRESSAWARE flag is currently the only solution to remedy out of memory errors.
After I applied the LAA patch to the MsAccess.exe running the application of my above-mentioned client, all the fully reproduceable out of memory issues were instantly gone!
© 1999 - 2021 by Philipp Stiefel - Privacy Policiy