[Bug]: OOM when a large project is compiled for the first time when generating BIRs #41407
Labels
Priority/Blocker
Team/CompilerFE
All issues related to Language implementation and Compiler, this exclude run times.
Team/DevTools
Ballerina Developer Tooling ( CLI, Test FW, Package Management, OpenAPI, APIDocs )
Type/Improvement
Description
This is originally observed when the openhealth projects are build for the first time. When we first compile a project the dependencies are downlaoded as Bala (source files) projects and compiled locally and the BIRs are generated locally. We cache these BIRs in ModuleContext and in BPackageSymbol for all the modules (dependencies) and consumes a lots of memory to keep these BIRs. If the project is big enough, there is a possibility that the program goes OOM. for example, the below code snippet can cause a OOM
We have done further optimisations on memory usages on lambda functions from the compiler frontend side and still we see OOM occurring due to compilation and BIR generation. Initially we saw that the OOM happened due to the capturedClosureEnv variable in lambda functions which we keep them unnecessarily. Once the links to those variables are removed now the OOM occur at the later stage. After analysing the heap dump, we saw that the cause for the OOM is the number of lambda functions. This is due to the number of module level annotations written. Each annotation is wrapped with a lambda function in compiler side. But if we further dig into the lambda functions, what actually take up the most of the memory is the body of the lambda functions, which are the annotation themselves.
In the above image, 1, 2, 3 are the ModuleContext, BPackageSymbol and the BIRPackage, which take up the most of the memory.
In ModuleContext, srcDocContextMap takes up the majority of the memory and the compilationUnit inside it, has lots of typeDefinitions and these type definitions have annotations which are represented by record literals. There is no way to remove those record literals as they are the real representation of the annotations. See the image below, there are a large number of DocumentContexts in a single ModuleContext.
In BPackageSymbol, We have the BIR stored as a field. This BIR mostly contains BIRFunctions mostly. Some module may have thousands of BIRFunctions due to annotation desugaring. But what takes up the memory is not the function itself, but the body of the function, which is the annotation itself. By looking at the Retained memory and comparing that to the shallow memory taken up by the function, I don't think removing the lambda functions will solve the problem.
With the front end changes we did to the compiler, the OOM occur only for a fresh build (Easily reproducible if we delete the BIR cache and keep the Bala cache). So to fix the OOM happening for such large projects, we have to either increase the memory allocation per JVM with the current design or we have to change the way we compile the dependencies and keeping them in the cache (right now we compile all the dependencies and keep their BIRs in the memory)
Adding @hasithaa @sameeragunarathne
Steps to Reproduce
No response
Affected Version(s)
No response
OS, DB, other environment details and versions
No response
Related area
-> Compilation
Related issue(s) (optional)
No response
Suggested label(s) (optional)
No response
Suggested assignee(s) (optional)
No response
The text was updated successfully, but these errors were encountered: