Skip to content

[GR-60436] Calling System.getenv() inside an isolate causes a memory leak #10234

Open
@alexfedorenchik

Description

@alexfedorenchik

Describe the Issue

Calling System.getenv() inside an isolate causes a memory leak

Using the latest version of GraalVM can resolve many issues.

GraalVM Version

openjdk 21.0.2 2024-01-16
OpenJDK Runtime Environment GraalVM CE 21.0.2+13.1 (build 21.0.2+13-jvmci-23.1-b30)
OpenJDK 64-Bit Server VM GraalVM CE 21.0.2+13.1 (build 21.0.2+13-jvmci-23.1-b30, mixed mode, sharing)

Operating System and Version

Darwin MBPRO 23.6.0 Darwin Kernel Version 23.6.0: Fri Jul 5 17:55:37 PDT 2024; root:xnu-10063.141.1~2/RELEASE_ARM64_T6030 arm64

Troubleshooting Confirmation

Run Command

  1. Run application
    TEST_LEAK=Hello ./TestLeak
  2. Run leaks command
    leaks $(pgrep -n TestLeak)

Expected Behavior

No leaks detected

Actual Behavior

Leak detected:

Process:         TestLeak [53536]
Path:            /Users/USER/*/TestLeak
Load Address:    0x102e54000
Identifier:      TestLeak
Version:         0
Code Type:       ARM64
Platform:        macOS
Parent Process:  zsh [18181]

Date/Time:       2024-12-05 09:08:46.120 +0100
Launch Time:     2024-12-05 09:07:55.328 +0100
OS Version:      macOS 14.6 (23G80)
Report Version:  7
Analysis Tool:   /Applications/Xcode.app/Contents/Developer/usr/bin/leaks
Analysis Tool Version:  Xcode 16.1 (16B40)

Physical footprint:         2657K
Physical footprint (peak):  3217K
Idle exit:                  untracked
----

leaks Report Version: 4.0
Process 53536: 525 nodes malloced for 66 KB
Process 53536: 1 leak for 1536 total leaked bytes.

    1 (1.50K) ROOT LEAK: 0x13e808200 [1536]

Steps to Reproduce

  1. create TestLeak class
import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.graalvm.nativeimage.IsolateThread;
import org.graalvm.nativeimage.Isolates;
import org.graalvm.nativeimage.Isolates.CreateIsolateParameters;
import org.graalvm.nativeimage.c.function.CEntryPoint;
import org.graalvm.nativeimage.c.function.CEntryPoint.IsolateThreadContext;

public class TestLeak {

    public static void main(String[] args) throws InterruptedException {
        System.out.println(System.getenv("TEST_LEAK"));

        var context = Isolates.createIsolate(CreateIsolateParameters.getDefault());
        isolate(context);
        Isolates.tearDownIsolate(context);

        System.out.println("Run 'leaks $(pgrep -n TestLeak)' to see leak");
        Thread.sleep(Duration.of(1, ChronoUnit.MINUTES));
    }

    @CEntryPoint
    private static void isolate(@IsolateThreadContext IsolateThread context) {
        System.out.println(System.getenv("TEST_LEAK"));
    }
}
  1. Build native image
    echo "Main-Class: TestLeak" > manifest.txt && javac TestLeak.java && jar -cvfm TestLeak.jar manifest.txt TestLeak.class && native-image -jar TestLeak.jar
  2. Run app
    TEST_LEAK=Hello ./TestLeak
  3. In a separate terminal run leaks
    leaks $(pgrep -n TestLeak)

Additional Context

No response

Run-Time Log Output and Error Messages

No response

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions