使用CoreRT与Npgsql编译.NET Core控制台应用遇内存耗尽问题求助
I've run into similar issues with CoreRT and Npgsql in Docker environments, and here are the steps that helped me resolve the out-of-memory error and get native compilation working:
1. Fix the Out-of-Memory Issue First
Exit code 137 almost always means the Linux OOM Killer terminated your ilc (CoreRT's IL compiler) process due to excessive memory usage. The immediate fix is to allocate more resources to your Docker container. Update your docker-compose.yml to add memory limits/reservations for the prototype service:
services: prototype: build: . depends_on: - database links: - database:database deploy: resources: limits: memory: 4G # Adjust based on your host's available RAM reservations: memory: 2G
If you're running the container directly without compose, use the --memory 4G flag with docker run.
2. Upgrade CoreRT to a Newer Version
You're using a very old alpha version (1.0.0-alpha-27919-02) which has known memory leaks and poor support for F# generics. Switch to a more recent preview release (e.g., RC2 or later):
- Update your project's NuGet references to use
Microsoft.NETCore.Nativeversion1.0.0-rc2-21480-01or newer. - Ensure your
nuget.configincludes necessary feeds:<configuration> <packageSources> <add key="dotnet-core" value="https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json" /> <add key="nuget.org" value="https://api.nuget.org/v3/index.json" /> </packageSources> </configuration>
3. Handle Npgsql's Reflection Dependencies
CoreRT's AOT compilation doesn't support dynamic reflection out of the box, and Npgsql relies heavily on it for type mapping. You have two options here:
Option A: Enable Runtime Reflection Support
Add this property to your HelloWorld.fsproj to let CoreRT generate required reflection metadata:
<PropertyGroup> <IlcEnableReflection>true</IlcEnableReflection> </PropertyGroup>
This is the quickest fix, though it will increase your binary size and memory footprint.
Option B: Use an rd.xml File for Explicit Directives
For better control and smaller binaries, create an rd.xml file in your project root to specify exactly which types/assemblies need reflection support:
<?xml version="1.0" encoding="utf-8"?> <Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata"> <Application> <!-- Preserve Npgsql's reflection metadata --> <Assembly Name="Npgsql" Dynamic="Required All"/> <!-- Add your application's assembly --> <Assembly Name="HelloWorld" Dynamic="Required All"/> <!-- Explicitly list your entity types if using them --> <Type Name="YourNamespace.YourEntityType" Dynamic="Required All"/> </Application> </Directives>
Reference the file in your .fsproj:
<ItemGroup> <RdXmlFile Include="rd.xml" /> </ItemGroup>
4. Optimize Compilation for Memory
Add these parameters to your dotnet publish command to reduce memory load during compilation:
dotnet publish -r linux-x64 -c Release -v detailed -o outside \ -p:IlcOptimizationLevel=Os \ # Optimize for size (cuts memory usage) -p:IlcDisableCppExceptionHandling=false \ # Disable if you don't need C++ exceptions -p:IlcGenerateCompleteTypeMetadata=false # Skip unused type metadata
5. Verify F# Specific Behavior
F#'s type system and generics can be trickier for CoreRT than C#. Test with a minimal C# console app using the same Npgsql and CoreRT setup:
- If the C# app compiles successfully, the issue likely stems from F#-specific constructs in your code (e.g., complex generics, higher-order functions). Try simplifying your F# code: avoid anonymous types in database queries, use concrete types instead of abstractions where possible, and reduce nested generics.
Final Notes
Yes, it's absolutely possible to use CoreRT with Npgsql successfully—many developers have gotten this working with the right configuration. The key steps are addressing memory constraints, updating CoreRT to a more stable version, and handling the reflection requirements that Npgsql depends on.
内容的提问来源于stack exchange,提问作者lpeixotoo

