Webclient:java.lang.OutOfMemoryError:直接缓冲内存

2024-02-17

我在 Web 客户端收到 java.lang.OutOfMemoryError: Direct buffer memory 错误。

批处理作业每天运行。两次失败,第三次就通过了。

at org.springframework.retry.support.RetryTemplate.rethrow(RetryTemplate.java:532) ~[spring-retry-1.2.5.RELEASE.jar:na]
 Caused by: java.lang.OutOfMemoryError: Direct buffer memory
at reactor.netty.http.client.HttpClientDoOnError$OnErrorTcpClient.connect(HttpClientDoOnError.java:242) ~[reactor-netty-0.9.11.RELEASE.jar:0.9.11.RELEASE]

我在日志中找到了 JVM 内存配置。它正在云铸造厂中运行。

JVM Memory Configuration: -Xmx342549K -Xss1M -XX:ReservedCodeCacheSize=240M -XX:MaxDirectMemorySize=10M -XX:MaxMetaspaceSize=194026K

失败的代码:

    @Retryable(maxAttemptsExpression = "#{${remote.retry.maxAttempts}}", backoff = @Backoff(delayExpression = "#{${remote.retry.delay}}"))
    public Optional<JobStatusResponseDTO> getStatus(String jobNumber, String accountNumber) {
        return broadridgeClient.getStatus(accountNumber, jobNumber);
    }

      @CircuitBreaker(maxAttemptsExpression = "#{${remote.circuitBreaker.maxAttempts}}",
            openTimeoutExpression = "#{${remote.circuitBreaker.openTimeout}}", resetTimeoutExpression = "#{${remote.circuitBreaker.resetTimeout}}")
    public Optional<JobStatusResponseDTO> getStatus(String account, String jobNumber) {

        JobStatusRequestDTO request = new JobStatusRequestDTO();
        request.setAccount(account);
        request.setJobNumber(jobNumber);

        JobStatusResponseDTO jobStatus;
        jobStatus = client.post()
                .uri(PATH)
                .body(BodyInserters.fromValue(request))
                .exchange()
                .elapsed()
                .flatMap(response -> {
                    
                    if (response.getT2().statusCode() == HttpStatus.NO_CONTENT) {
                        return Mono.empty();
                    } else if (isClientOrServerError(response.getT2())) {
                        return Mono.error(new RemoteClientException(String.format("Job status is not received: %s", response.getT2().statusCode())));
                    }
                    return response.getT2().bodyToMono(JobStatusResponseDTO.class);
                })
                .block();
        return Optional.ofNullable(jobStatus);
    }

Edit 1:

我还发现 Cloud Foundry 正在为堆设置低内存 我正在使用 CF 任务来运行它。

cf run-task ipbol-proxy-batch "JAVA_OPTS=\"-agentpath:\$PWD/.java-buildpack/oracle_jre/bin/jvmkill-1.16.0_RELEASE=printHeapHistogram=1 -Djava.io.tmpdir=\$TMPDIR -Djava.security.egd=file:///dev/urandom -XX:ActiveProcessorCount=\$(nproc) -Dspring.batch.job.names=${job_name} -Dbatch.run.historic=${run_historic_files} -Dorg.cloudfoundry.security.keymanager.enabled=false -Dorg.cloudfoundry.security.trustmanager.enabled=true -Djava.ext.dirs= -Djava.security.properties=\$PWD/.java-buildpack/java_security/java.security \$JAVA_OPTS\" && CALCULATED_MEMORY=\$(\$PWD/.java-buildpack/oracle_jre/bin/java-buildpack-memory-calculator-3.13.0_RELEASE -totMemory=\$MEMORY_LIMIT -loadedClasses=31842 -poolType=metaspace -stackThreads=250 -vmOptions=\"\$JAVA_OPTS\") && echo JVM Memory Configuration: \$CALCULATED_MEMORY && JAVA_OPTS=\"\$JAVA_OPTS \$CALCULATED_MEMORY\" && KEYSTORE_PARAMS=\$(\$PWD/.java-buildpack/oracle_jre/bin/java -jar \$PWD/.java-buildpack/oracle_jre/keystore-manager-0.1.1.jar) && JAVA_OPTS=\"\$JAVA_OPTS \$KEYSTORE_PARAMS\" && MALLOC_ARENA_MAX=2 VCAP_SERVICES=\$(for i in {1..10}; do \${PWD}/.java-buildpack/mv_decryptor/jpmc-mvdecryptor && exit 0; sleep 3; done; kill \$\$) SERVER_PORT=\$PORT eval exec \$PWD/.java-buildpack/oracle_jre/bin/java \$JAVA_OPTS -cp \$PWD/.::\$PWD/.java-buildpack/container_security_provider/container_security_provider-1.16.0_RELEASE.jar org.springframework.boot.loader.JarLauncher" ipbol-proxy-batch

Edit 2:

我已经更新了代码以在每种情况下使用响应。尽管如此,我还是得到了相同的“java.lang.OutOfMemoryError:直接缓冲内存”

public Optional<JobStatusResponseDTO> getStatus(String account, String jobNumber) {

        JobStatusRequestDTO request = new JobStatusRequestDTO();
        request.setAccount(account);
        request.setJobNumber(jobNumber);
        Optional<JobStatusResponseDTO> responseDTO = Optional.empty();

        final Object block = client.post()
                .uri(PATH)
                .body(BodyInserters.fromValue(request))
                .exchange()
                .elapsed()
                .flatMap(response -> {
                   
                    if (response.getT2().statusCode() == HttpStatus.NO_CONTENT) {
                        return response.getT2().bodyToMono(Void.class).thenEmpty(Mono.empty());

                    } else if (isClientOrServerError(response.getT2())) {
                        return response.getT2().bodyToMono(Void.class).thenEmpty(Mono.error(new RemoteClientException(String.format("Job status is not received: %s", response.getT2().statusCode()))));
                    }
                    return response.getT2().bodyToMono(JobStatusResponseDTO.class);
                })
                .block();
        
        if(block!= null && block instanceof JobStatusResponseDTO)
        {
            responseDTO = Optional.of((JobStatusResponseDTO)block);
        }
        return responseDTO;
    }

我的组织仓库中没有 spring webflux 5.3。所以不能用那个。

这是默认内存配置

-Xmx1387828K -Xss1M -XX:ReservedCodeCacheSize=240M -XX:MaxDirectMemorySize=10M -XX:MaxMetaspaceSize=197323K

从 Spring 5.3 开始exchange()该方法在 Web 客户端上已被弃用,因为它可能导致内存和连接泄漏。通过使用exchange()您有责任使用每个场景的响应内容。

从上面的代码示例来看,您在成功和错误情况下都不会消耗主体。

您还可以设置以下属性以从 Netty 获取有关泄漏来自何处的一些附加信息。

-Dio.netty.leakDetection.level=偏执狂

交换Javadoc https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/reactive/function/client/WebClient.RequestHeadersSpec.html#exchange--

Netty 泄漏检测文档 https://netty.io/wiki/reference-counted-objects.html#leak-detection-levels

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Webclient:java.lang.OutOfMemoryError:直接缓冲内存 的相关文章

  • 我对线程失去了理智

    我想要这个类的对象 public class Chromosome implements Runnable Comparable
  • 自定义列表字段点击事件

    我正在编写一个应用程序 其中我创建了用于显示列表视图的自定义列表字段 我的 CustomListField 包含连续的一个图像和文本 我正在通过单击列表字段行获取字段更改侦听器 但我也想将字段更改侦听器放在图像上 谁能告诉我我该怎么做 这是
  • java中如何知道一条sql语句是否执行了?

    我想知道这个删除语句是否真的删除了一些东西 下面的代码总是执行 else 是否删除了某些内容 执行此操作的正确方法是什么 public Deleter String pname String pword try PreparedStatem
  • 如何从控制器访问片段中的片段?

    我有一个名为 cutleryCustomerSearch 的视图 其中包含 替换 一个片段 div div div div 在此片段中 我有一个表 我喜欢通过 ajax 更新它 table 我如何设置处理 ajax 请求的控制器方法的返回
  • 将类转换为 JSONObject

    我有好几堂这样的课 我想将类转换为 JSONObject 格式 import java io Serializable import com google gson annotations SerializedName public cla
  • 为什么 jar 执行的通配符在 docker CMD 中不起作用?

    我有一个Dockerfile与以下CMD启动我的 Spring Boot 应用程序 FROM java 8 jre CMD java jar app file jar 当我尝试从创建的图像启动容器时 我得到 Error Unable to
  • JAXB - 忽略元素

    有什么方法可以忽略 Jaxb 解析中的元素吗 我有一个很大的 XML 文件 如果我可以忽略其中一个大而复杂的元素 那么它的解析速度可能会快很多 如果它根本无法验证元素内容并解析文档的其余部分 即使该元素不正确 那就更好了 例如 这应该只生成
  • 在 Spring 中为 @Pathvariable 添加类级别验证

    在发布这个问题之前 我已经做了很多研究并尝试了很多可用的解决方案 这是我陷入的棘手情况 我有一个 Spring 控制器 它有多个请求映射 它们都有 PathVariables 控制器如下所示 Controller EnableWebMvc
  • Mockito 和 Hamcrest:如何验证 Collection 参数的调用?

    我遇到了 Mockito 和 Hamcrest 的泛型问题 请假设以下界面 public interface Service void perform Collection
  • 在java程序中使用c++ Dll

    我正在尝试使用System LoadLibrary 使用我用 C 编写的一个简单的 dll UseDllInJava java import com sun jna Library import com sun jna Native imp
  • UseCompressedOops JVM 标志有什么作用以及何时应该使用它?

    HotSpot JVM 标志是什么 XX UseCompressedOops我应该做什么以及什么时候使用它 在 64 位 Java 实例上使用它 与不使用它 时 我会看到什么样的性能和内存使用差异 去年大多数 HotSpot JVM 都默认
  • Android - 存储对ApplicationContext的引用

    我有一个静态 Preferences 类 其中包含一些应用程序首选项和类似的内容 可以在那里存储对 ApplicationContext 的引用吗 我需要该引用 以便我可以在不继承 Activity 的类中获取缓存文件夹和类似内容 你使用的
  • Tomcat 6 未从 WEB-INF/lib 加载 jar

    我正在尝试找出我的 tomcat 环境中的配置问题 我们的生产服务器正在运行 tomcat 安装并从共享 NFS 挂载读取战争 然而 当我尝试使用独立的盒子 及其配置 进行同样的战争时 我收到下面发布的错误 有趣的是 如果我将 WEB IN
  • Azure Java SDK:ServiceException:ForbiddenError:

    尝试了基本位置检索器代码 如下所示 String uri https management core windows net String subscriptionId XXXXXXXX 5fad XXXXXX 9dfa XXXXXX St
  • 即使禁用安全性,OAuth 令牌 API 也无法在 Elastic Search 中工作

    我是 Elastic search 新手 使用 Elastic search 版本 7 7 1 我想通过以下方式生成 OAuth 令牌弹性搜索文档 https www elastic co guide en elasticsearch re
  • 在 Java 中通过 D-Bus MPRIS 访问 Clementine 实例

    我使用 Clementine 作为音乐播放器 它可以通过 D Bus 命令进行控制 在命令行上 使用 qdbus 我可以 Start Stop 暂停播放器 强制它跳过播放列表中的歌曲 检查播放列表的长度 检查播放列表中当前播放的曲目及其元数
  • 检测到 JVM 正在关闭

    我有一个使用 addShutdownHook 处理 Ctrl C 的 Swing 应用程序 它工作正常 直到我的关闭任务之一调用一个在正常情况下更改 JLabel 文本的函数 此时它挂起 我认为问题是 Swing EDT 已终止或正在等待某
  • Spring 作为 JNDI 提供者?

    我想使用 Spring 作为 JNDI 提供程序 这意味着我想在 Spring 上下文中配置一个 bean 可以通过 JNDI 访问该 bean 这看起来像这样
  • 设置 TreeSet 的大小

    有没有办法像数组一样对 Java 集合中的 TreeSet 进行大小限制 例如我们在数组中 anArray new int 10 数组具有固定长度 在创建数组时必须指定该长度 A TreeSet当您向其中添加元素时会自动增长 您无法设置其大
  • GAE 无法部署到 App Engine

    我正在尝试从 Eclipse 发布 Web 应用程序 我在 GAE 上创建了四个项目 可以通过登录我的帐户并查看控制台来查看它们 我已经改变了appengine web xml到项目的应用程序 ID 如果我将其更改为 GAE 上第一个创建的

随机推荐