Friday, February 15, 2013

Insufficient Memory to Run Script - MaxBufferSize

Note: This is an old post I never got around to posting. It was extremely helpful to me a bunch of other people I shared it with in the AX community back in 2008 - 2010 so hopefully it still is.

In previous versions of AX (AX 2009, AX 4.0, AX 3.0, etc), there was an issue where a file (mainly XML) coming into AX through a custom interface would be too large for AX to handle. It would spit out the error 'Insufficient Memory to Run Script' or something very similar to that.

When I'd hear this from clients, it usually was not at go live or even a month or two after. It was usually 3 or months and due to an unusually large order coming into the system that exceed our max testing limit for them. Since I was usually involved with other clients and this was more of an after hours support thing, I wrote a job to provide to clients to gather the info for me in the registry so I didn't have to log in to check. Unfortunately, it was very common for people to think they changed the settings when doing phone troubleshooting which didn't help anybody out so this solved that issue.

This solution was pretty solid. If you have problems, put a comment in the section below. I can help. While its been a while, I'm pretty familiar with this code since I wrote it and didn't rip it from other people like some people do.

Here's what I had from that old post:

http://blogs.msdn.com/b/emeadaxsupport/archive/2009/06/15/error-executing-code-insufficient-memory-to-run-script.aspx

TROUBLESHOOT: I've encountered an issue where I've updated the server and client registry settings as well as the individual .axc files to handle a larger variable but we were still hitting an issue.  When we would click on the grid of a table with the large XML string, it would immediately give us the Insufficient memory to run script error even without processing it.  Restarting the AOS didn't help either. This same process had been done to another environment without a problem so why just this one environment?

The way I solved it was to rebuild the .axc file using the client config with the new registry settings.  This cleared it right up with no problems. I'm guessing it is some kind of bug or something because the settings between the two environments were exact.

To test the max buffer size, do the following

// DAX Dude - Feb 25, 2011 
static void daxMaxBufferXMLVariableLoadTest(Args _args)
{
   // Job variables
   #define.FILEEXT_XML ('.xml')
   str xmlLocation = "C:\\Users\\daxdude\\Desktop\\issues\\02-25 failure\\";
   str fileName = "TEST";
   str file = xmlLocation + fileName + #FILEEXT_XML;
   XML xml; 
   Boolean loadedFile;
   int64 fileSizeInBytes;

   // Registry Retrieval
   #define.AOSRegistryPath(@'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Dynamics Server\5.0')
   #define.ValueName(maxbuffersize)
   #define.ValueType(REG_SZ)

   InteropPermission interopPermission = new InteropPermission(InteropKind::ClrInterop);
   System.String contents;
   str axAOSName = "01"; 
   str axConfigName = "Debug";
   str regValue;
   str axRegLocation;
   str axRegKeyName = "maxbuffersize";
   str axRegAXName = "application";
   str axEnvironment;

   // XML test objects
   System.IO.StringWriter stringWriter;
   System.Xml.XmlTextWriter textWriter;
   System.Xml.XmlDocument xmlDocument = new System.Xml.XmlDocument();

   // !!!NOTE - Cannot use base AX's XmlDocument class. Must use a System.Xml.XmlDocument type
   //XMLDocument xmlDoc = new XMLDocument();
   ;

   try
   {
      // Check the current registry value
      interopPermission.assert();

      info ('------ CHECK FOR MAX BUFFER SIZE ON AOS ------');

      axRegLocation = #AOSregistryPath + '\\' + axAOSName + '\\' + axConfigName;

      contents = Microsoft.Win32.Registry::GetValue(axRegLocation, axRegAXName, null);
      axEnvironment = System.Convert::ToString(contents);

      if (axEnvironment)
      {
         contents = Microsoft.Win32.Registry::GetValue(axRegLocation, axRegKeyName, null);
 
         if(contents)
         {
            regValue = System.Convert::ToString(contents);
            contents = Microsoft.Win32.Registry::GetValue(axRegLocation, axRegAXName, null);
            info (strFmt("%1 is set to %2 MB", axEnvironment, regValue));
         }
         else
         {
            warning (strFmt('%1 does not have the registry value %2', axEnvironment, axRegKeyName));
            info ('Max Buffer Size (default) - 4 MB variable limit');
            Warning ('NOTE: Make sure to change the .axc file and client configuration. This only measures the AOS setting');
         }
      }
      else
      {
         error (strFmt("Could not find AX registry location: %1", axRegLocation));
      }

      CodeAccessPermission::revertAssert();

      info ('');
      info ('------ XML SIZE TEST-------------------------');

      // Play with loading the XML
      if (WinAPI::fileExists(file))
      {
         fileSizeInBytes = WinAPI::fileSize(file);

         info (file);
         info (strFmt("File Size - %1 KB/%2 MB", fileSizeInBytes/1000, fileSizeInBytes/1000000));

         xmlDocument.Load(file);
         loadedFile = true;
         stringWriter = new System.IO.StringWriter();
         textWriter = new System.Xml.XmlTextWriter(stringWriter);
         xmlDocument.WriteTo(textWriter);

         // !!!NOTE - Cannot use base AX's XmlDocument class. Must use a System.Xml.XmlDocument type
         //xmlDoc.writeTo(textWriter);

         xml = stringWriter.ToString();

         if (xml)        
         {
            info ('!! Variable loaded !!');
         }
      }
      else
      {
         throw error ('Test XML not found');
      }
   }
   catch
   {   
      error ('No fun here');   
   }
}

1 comment: