Java 在此时间窗口中已检测到内存耗尽的早期症状

Java 在此时间窗口中已检测到内存耗尽的早期症状,java,garbage-collection,newrelic,Java,Garbage Collection,Newrelic,我很难理解new relic抛出的以下错误/警告: 在此时间窗口中已检测到内存耗尽的早期症状 以下是基于日志的剖面图 我想了解: 为什么伊甸园的空间从来没有完全清洁时,一个小GC发生 根据日志中的GC行为,蓝色和黄色是否分别对应于主要GC和次要GC 为什么GC总是在收集 红色区域是New Relic发出记忆耗尽警报的时间。但是,堆还没有满。这是否会触发断路器转换到断开状态 我在向我们的任务执行器服务(例如:executorService.submit(()->restcontexto.pos

我很难理解new relic抛出的以下错误/警告:

在此时间窗口中已检测到内存耗尽的早期症状

以下是基于日志的剖面图

我想了解:

  • 为什么伊甸园的空间从来没有完全清洁时,一个小GC发生
  • 根据日志中的GC行为,蓝色和黄色是否分别对应于主要GC和次要GC
  • 为什么GC总是在收集
  • 红色区域是New Relic发出记忆耗尽警报的时间。但是,堆还没有满。这是否会触发断路器转换到断开状态
  • 我在向我们的任务执行器服务(例如:
    executorService.submit(()->restcontexto.post(…)
    )提交新的REST调用时注意到了这种行为。我尝试提交了一个
    logger.info()
    ,它工作正常,但似乎做了一个长轮询才是问题所在。下面是我的GC配置:

    • 并行GC
    • -Xms2048m-Xmx2048m
    谢谢你的见解

  • 垃圾收集器是守护进程线程,在JVM启动时启动,在所有非守护进程线程停止时停止。GC一直在运行,而应用程序从不干净的原因很可能是因为总是有东西要收集(甚至可能是后台任务)。最终用户无法控制垃圾收集器

  • 我真的不明白你的问题

  • 见1

  • 您的堆不必已满才能触发警报。默认情况下,文物设置设置如下所示:

    Memory threshold: 20%
    Garbage collection CPU threshold: 10%
    
  • 这些当然可以调整,但它们基本上意味着,如果可用内存小于阈值,则会触发警报

    正如您在提交REST请求时所注意到的(取决于实际提交的请求以及您的应用程序的结构/设计方式),对于应用程序来说,此特定请求可能会“繁重”,因此它可能会比您预期的占用更多内存

  • 您正在使用的年轻一代收集器是。此收集器并行使用多个线程。因此,没有一个全站式的世界暂停来收集年轻一代的所有节点。因此,伊甸园空间的可用空间可能不会一直下降到0%
  • 图表上的黄线和蓝线与主要或次要GC事件不对应。这取决于图表本身。但是,在垃圾收集CPU时间图表中,黄色区域对应于花费在年轻一代收集器PS cleave上的CPU时间,而蓝色区域对应于花费在旧一代收集器PS Mark Sweep上的CPU时间
  • 垃圾收集器一直在运行,因为年轻一代、幸存一代和老一代收集器都使用多个后台线程。这可以最大限度地减少单线程垃圾收集器中周期性发生的停止全局暂停次数
  • 从图表上看,是的。红色区域是New Relic确定可能需要暂停程序并完全清理堆以便程序可以继续运行的时间段。通常,并发收集器最终只是延迟停止世界暂停,而不是完全阻止它们。有关详细信息,请参见关于垃圾收集的。有关断路器跳闸条件的详细信息,请参阅

  • 对你的观点有一些评论:1。如果我没有错的话,我已经读到年轻一代的收集是一个停止世界收集所有4 GC。并行收集器的问题是GC使用多个线程来进行收集,作为一个连续的集合,在一个年轻的收集之后,应该完全回收内存。我可以看到,当伊甸园的大小减少时,幸存者和旧的增加,然而伊甸园永远不会被清除。谢谢你的链接