Question:
Why Running Out of Memory Occurs in the Vault SDK Code?
Answer:
If running out of memory in SDK extensions, User-Defined Services (UDS) may be able to help. SDK extensions that perform complex operations with bulk data can run into memory limits. Vault enforces a 40 MB memory limit for all SDK extensions such as triggers and actions. SDK extensions consume memory when a variable is instantiated or a service method is used. This memory is not freed up until the extension finishes executing. When processing bulk data, developers can use up all the memory allowed, resulting in an error dialog displaying the memory-exceeded error being displayed to the user.
User-Defined Services allow you to reclaim the memory used by wrapping memory-intensive code into a reusable service. The memory used by the User-Defined Service methods is returned when the methods exits. Only the memory used by the return value of the method counts towards the limit.
So what is the difference between User-Defined Services and User-Defined Classes (UDC)? User-Defined Classes allow developers to structure code into reusable methods; however, User-Defined Class methods do not return the used memory back to the memory limit. Therefore, User-Defined Classes are best used for sharing and processing complex data objects or for structuring code for reuse, typically for use cases that won’t deal with large amounts of data and run into memory issues.
User-Defined Class |
User-Defined Service |
|
|
To see the difference, let’s look at an example of a Record Trigger which is called as a result of a data load of 500 records via Vault Loader. In this case, the inserted data may require field defaulting, validation, grouping and other processing before being inserted. Processing records in this manner requires holding the record in memory while the processing logic executes. If a record uses 1 MB of memory, a User-Defined Class implementation would use up 40 MB of memory before hitting the limit and displaying an error. Whereas, with a User-Defined Service, the memory usage would be only of the return values of the User-Defined Service methods and any memory used in code outside of the User-Defined Service. This is because the memory used by the record and the processing logic is released when the User-Defined Service method completes. The memory usage differences between User-Defined Services and User-Defined Classes can be verified using the LogService’s logResourceUsage method. Refer to the Javadocs for details about using this service.
Using a User-Defined Service is just like using a Vault SDK provided service: it must first be located using the ServiceLocater. After it is located, the methods of the User-Defined Service can be called. Refer to the Javadocs for details about using this service.
// Locating the User-Defined Service and the Log Service
ProductSearchUserDefinedService productSearchUserDefinedService = ServiceLocator.locate(ProductSearchUserDefinedService.class);
LogService logService = ServiceLocator.locate(LogService.class);
// Log Resource Usage before the UDS method is called
logService.logResourceUsage("Before reduceProductQuantity Method Call: ");
// Use UDS method
productSearchUserDefinedService.reduceProductQuantity(doProductsExist.values(), orderQuantityMap);
logService.logResourceUsage("After reduceProductQuantity Method Call: ");
In summary, User-Defined Services are a tool that can be used to lower the memory usage of SDK code and make code reusable. User-Defined Services are best suited for scenarios involving bulk data processing that don’t require data to be shared among methods or triggers/actions. User-Defined Services are preferred over User-Defined Classes when memory usage is a concern as they do not retain any data after the method exits.
To learn more about User-Defined Services, how to create and use them, please view the sample code project on Github. The documentation for User-defined services can be found in the Developer Portal.
Related Documentation:
Vault Help Documentation: