DI API Memory Leak in SAP Business One 9.0

DI API as we know is an important component in SAP Business One which allows other third party applications to interact with the ERP system. It allows to push and receive data to/from SAP Business One. Though new integration components are available like DI Server which allows the data to be synced in batch provides greater performance, still DI API is widely used in many solutions offered by SAP Partner. One of the biggest reason of using this is no additional license requirement, while DI Server License comes up at an additional cost of few hundred euros.

But in current release of SAP Business One 9.0, it is reported by several SAP Partners and consultants that DI API faces a fatal bug of Memory Leak while exchanging the data. Let’s have a detail look of incidents reported in several forums regarding the DI API Memory Leak in SAP Business One 9.0.

Problem

With each API calls DI API exceeding the usage of RAM even when running the same process, eventually reaching the threshold point of getting free RAM and crashing the subsequent process which accessing the DI API. So in this way the worker process finally hang the application and crashes it.

Example 1:

Reported in SCN, below Sales Order creation process before running has an available free RAM of 6GB. This is a dummy Sales Order Creation Process in SAP Business One through DI API:


 -------------------------
 Declaring SAP objects...
-------------------------
SAPbobsCOM.Company CurrentCompany  = null;
SAPbobsCOM.Documents Order = null;
SAPbobsCOM.BusinessPartners bp  = null;
SAPbobsCOM.Items Items = null;
SAPbobsCOM. AdditionalExpenses Expenses  = null;
//-------------------------
Opening a company object
-------------------------
SAPbobsCOM.Company CurrentCompany  = GetSAPCompany (SessionID);
if (CurrentCompany != null)
{
Order = (SAPbobsCOM.Documents) CurrentCompany.GetBusinessObject (BoObjectTypes.oOrders);
bp = (SAPbobsCOM.BusinessPartners) CurrentCompany.GetBusinessObject (BoObjectTypes.oBusinessPartners);
Items = (SAPbobsCOM.Items) CurrentCompany.GetBusinessObject (BoObjectTypes.oItems);
Expenses = (SAPbobsCOM. AdditionalExpenses) CurrentCompany.GetBusinessObject (BoObjectTypes. oAdditionalExpenses) ;
}
//--------------------------------------------------
Here would be the code to create  a Sales Order...
//--------------------------------------------------
//------------------------
// Releasing everything...
//------------------------
if (Order != null)
{
System.Runtime.InteropServices. Marshal.ReleaseComObject (Order);
Order = null;
}

if (bp != null)
{
System.Runtime.InteropServices. Marshal.ReleaseComObject (bp);
bp = null;
}
if (Items != null)
{
System.Runtime.InteropServices. Marshal.ReleaseComObject (Items);
Items = null;
}
if (Expenses != null)
{
System.Runtime.InteropServices. Marshal.ReleaseComObject(Expenses);
 Expenses = null;
}
if (CurrentCompany != null)
{
if(CurrentCompany.Connected)
CurrentCompany.Disconnect();

System.Runtime.InteropServices. Marshal.ReleaseComObject (CurrentCompany);
CurrentCompany = null;
}

Initially memory taken was 40 MB, releasing 36 MB after each time execution and 4 MB of memory usage is growing with each Sales Order creation. Eventually in some system integration such as eCommerce where there is a need to push thousands of Sales Order per hour, this process will shorten the Free RAM in no time and hangs or crashes the application like below

Faulting
application name: w3wp.exe, version: 7.5.7601.17514, time stamp: 0x4ce7afa2

Faulting module
name: B1_DIInternalFields90Ace.dll, version: 9.0.56.0, time stamp: 0x51799cf5

Exception code:
0xc0000005

Fault offset:
0x0000000000017917

Faulting process
id: 0x1a74

Faulting
application start time: 0x01ceb48157da7b5d

Faulting
application path: c:\windows\system32\inetsrv \w3wp.exe

Faulting module
path: C:\Program Files\SAP\SAP Business One DI API\DI API
90\B1_DIInternalFields90Ace.dll

Report Id:
744a7aa3-207a-11e3-ad28-00155d400702

Solution

It is mostly advised by other consultants not to use DI API until there is some updated patch level released with this fix, still below solutions are mentioned. You can take a look and try if this helps:

Garbage Collector

Force the system garbage collector

GC.Collect();

GC.WaitForPendingFinalizers();

GC.Collect();

Alternative Method

.Net franmework won’t let you unload any loaded assembly and DI-proxy is only an assembly. The solution is using alternative method like:

  • Going at a minimum to DI-Server – B1WS which consumes less memory, but for which you can force the unload of the service and by doing so to force it to release all its memory,
  • Going ideally to B1if, which with its own DI-proxy mechanism will be able to restart periodically,

If can’t change from API, move all the business logic in a separate process (exe, not web-service neither DLL) which will be called by your web page and removed from memory when its job is ended.

integrate-sap-business-one-with-webstore-appseconnect

You may also like:
How to Manage Discounts from Shopify to SAP Business One
Data Transfer in SAP Business One version for HANA
SAP Business One Sales App for Android and iOS: In-depth Feature List