cloudfoundry / cloudfoundry/cf-java-client

Memory leak since version `5.8.0`

Offen
#1,186 2 Kommentare 1 Reaktion 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Vorherrschende Sprache
Java
Sterne
334
Forks
319
PR-Merge-Kennzahlen
Keine gemergten PRs in 30 T.

Beschreibung

The following code results in a memory leak:

Main.java
package org.example;

import org.cloudfoundry.client.v2.users.GetUserResponse;
import org.cloudfoundry.client.v3.roles.RoleType;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.util.List;

@SpringBootApplication
public class Main {
    public static void main(String[] args) {
        System.out.println("Hello world!");

        SpringApplication.run(Main.class, args);

        triggerCalls();
    }

    public static void triggerCalls() {
        CloudFoundryService cloudFoundryService = new CloudFoundryService();

        for (int i = 0; i < 100; i++) {
            try {
                GetUserResponse getUserResponse = cloudFoundryService.getUser("c33c0489-2f84-4ddc-9b6a-e4f73c8be628");
                System.out.println("Fetch " + i + " : " + getUserResponse.getEntity().getUsername());

                List<RoleType> roleTypes = cloudFoundryService.getUserRoles();

            } catch (Exception e) {
            }
        }

        System.out.println("DONE");

    }
}
CloudFoundryService.java
package org.example;

import org.cloudfoundry.client.v2.users.GetUserRequest;
import org.cloudfoundry.client.v2.users.GetUserResponse;
import org.cloudfoundry.client.v3.roles.ListRolesRequest;
import org.cloudfoundry.client.v3.roles.RoleResource;
import org.cloudfoundry.client.v3.roles.RoleType;
import org.cloudfoundry.reactor.DefaultConnectionContext;
import org.cloudfoundry.reactor.client.ReactorCloudFoundryClient;
import org.cloudfoundry.reactor.tokenprovider.PasswordGrantTokenProvider;

import java.util.List;
import java.util.stream.Collectors;

public class CloudFoundryService {

    private String user = "user";
    private String password = "1234";

    public GetUserResponse getUser(String userId) {
        return this.getClient().users().get(GetUserRequest.builder().userId(userId).build()).block();
    }

    public List<RoleType> getUserRoles() {
        return this.getClient().rolesV3().list(ListRolesRequest.builder().build())
                .map(userRoleListResponse -> {
                    return userRoleListResponse.getResources().stream()
                            .map(RoleResource::getType)
                            .collect(Collectors.toList());
                })
                .block();

    }

    ReactorCloudFoundryClient getClient() {
        return ReactorCloudFoundryClient.builder()
                .connectionContext(this.connectionContext())
                .tokenProvider(this.tokenProvider())
                .build();
    }

    DefaultConnectionContext connectionContext() {
        return DefaultConnectionContext.builder()
                .apiHost("api.domain.com")
                .build();
    }

    PasswordGrantTokenProvider tokenProvider() {
        return PasswordGrantTokenProvider.builder()
                .password(this.password)
                .username(this.user)
                .build();
    }
}

Here's a stack trace:

Stacktrace
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR Exception in thread "main" java.lang.reflect.InvocationTargetException
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at java.base/java.lang.reflect.Method.invoke(Unknown Source)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at org.springframework.boot.loader.Launcher.launch(Launcher.java:108)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:88)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR Caused by: java.lang.OutOfMemoryError: Cannot reserve 49152 bytes of direct buffer memory (allocated: 10444808, limit: 10485760)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at java.base/java.nio.Bits.reserveMemory(Unknown Source)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at java.base/java.nio.DirectByteBuffer.<init>(Unknown Source)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at java.base/java.nio.ByteBuffer.allocateDirect(Unknown Source)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at io.netty.channel.unix.Buffer.allocateDirectWithNativeOrder(Buffer.java:40)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at io.netty.channel.epoll.EpollEventArray.<init>(EpollEventArray.java:58)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at io.netty.channel.epoll.EpollEventLoop.<init>(EpollEventLoop.java:95)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at io.netty.channel.epoll.EpollEventLoopGroup.newChild(EpollEventLoopGroup.java:187)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at io.netty.channel.epoll.EpollEventLoopGroup.newChild(EpollEventLoopGroup.java:37)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at io.netty.util.concurrent.MultithreadEventExecutorGroup.<init>(MultithreadEventExecutorGroup.java:84)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at io.netty.util.concurrent.MultithreadEventExecutorGroup.<init>(MultithreadEventExecutorGroup.java:60)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at io.netty.util.concurrent.MultithreadEventExecutorGroup.<init>(MultithreadEventExecutorGroup.java:49)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at io.netty.channel.MultithreadEventLoopGroup.<init>(MultithreadEventLoopGroup.java:59)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at io.netty.channel.epoll.EpollEventLoopGroup.<init>(EpollEventLoopGroup.java:114)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at io.netty.channel.epoll.EpollEventLoopGroup.<init>(EpollEventLoopGroup.java:101)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at io.netty.channel.epoll.EpollEventLoopGroup.<init>(EpollEventLoopGroup.java:78)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at reactor.netty.resources.DefaultLoopEpoll.newEventLoopGroup(DefaultLoopEpoll.java:93)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at reactor.netty.resources.DefaultLoopResources.cacheNativeServerLoops(DefaultLoopResources.java:254)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at reactor.netty.resources.DefaultLoopResources.cacheNativeClientLoops(DefaultLoopResources.java:219)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at reactor.netty.resources.DefaultLoopResources.onClient(DefaultLoopResources.java:139)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at reactor.netty.transport.NameResolverProvider.newNameResolverGroup(NameResolverProvider.java:473)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at reactor.netty.transport.ClientTransportConfig.lambda$getOrCreateResolver$0(ClientTransportConfig.java:240)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(Unknown Source)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at reactor.netty.internal.util.MapUtils.computeIfAbsent(MapUtils.java:46)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at reactor.netty.transport.ClientTransportConfig.getOrCreateResolver(ClientTransportConfig.java:239)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at reactor.netty.transport.ClientTransport.runOn(ClientTransport.java:352)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at reactor.netty.transport.ClientTransport.runOn(ClientTransport.java:42)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at reactor.netty.transport.Transport.runOn(Transport.java:249)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at org.cloudfoundry.reactor._DefaultConnectionContext.configureHttpClient(_DefaultConnectionContext.java:265)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at org.cloudfoundry.reactor._DefaultConnectionContext.getHttpClient(_DefaultConnectionContext.java:105)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at org.cloudfoundry.reactor.DefaultConnectionContext.access$2201(DefaultConnectionContext.java:26)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at org.cloudfoundry.reactor.DefaultConnectionContext$InitShim.getHttpClient(DefaultConnectionContext.java:126)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at org.cloudfoundry.reactor.DefaultConnectionContext.<init>(DefaultConnectionContext.java:83)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at org.cloudfoundry.reactor.DefaultConnectionContext.<init>(DefaultConnectionContext.java:26)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at org.cloudfoundry.reactor.DefaultConnectionContext$Builder.build(DefaultConnectionContext.java:1167)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at org.example.CloudFoundryService.connectionContext(CloudFoundryService.java:45)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at org.example.CloudFoundryService.getClient(CloudFoundryService.java:37)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at org.example.CloudFoundryService.getUser(CloudFoundryService.java:21)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at org.example.Main.triggerCalls(Main.java:25)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR at org.example.Main.main(Main.java:17)
24/07/2023, 08:31:01 [APP/PROC/WEB/0] ERR ... 8 more

It is not reproducible locally (macOS). We deploy this as a CloudFoundry app (linux).

It is not reproducible with version 5.7.0.

Beitragsleitfaden

Für dieses Repository ist kein Beitragsleitfaden indexiert

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginnen Sie mit dem bereitgestellten Reproducer aus Main.java und CloudFoundryService.java und verfolgen Sie anschließend die Stack-Frames von getClient(), connectionContext() und DefaultConnectionContext im Report. Führen Sie die wiederholten Aufrufe unter Linux oder Cloud Foundry aus und vergleichen Sie das Verhalten mit den Versionen 5.7.0 und 5.8.0. Als erledigt gilt die Aufgabe, wenn die wiederholten Aufrufe den Speicher für direkte Puffer nicht mehr erschöpfen und die Regression durch eine reproduzierbare Verifizierung abgedeckt ist.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
java
Bereich
api, backend
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
45/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.