【问题标题】:GAE using much more memory than my Java applicationGAE 使用的内存比我的 Java 应用程序多得多
【发布时间】:2021-01-25 04:05:39
【问题描述】:

我有一个在 Google App Engine 上运行的 Java 应用程序(Spring Boot);但是,我发现我的 Java 应用程序内存消耗与 GAE 显示的仪表板之间存在奇怪的差异。

在我使用 VisualVM 的本地机器上,我可以看到它即使在高峰时间消耗也不会超过 100MB,我添加了一个 servlet 来返回使用的内存量:

@GetMapping("/")
public String index() {
  Runtime rt = Runtime.getRuntime();
  long total = rt.totalMemory();
  long free = rt.freeMemory();
  long used = total - free;
  return "Total: " + total / 1024 / 1024 + "MB<br>Used: " + used / 1024 / 1024 + "MB<br>Free: " + free / 1024 / 1024 + "MB";
}

我在 GAE 中部署的应用现在返回:

Total: 91MB
Used: 69MB
Free: 21MB

与此同时,GAE 仪表板显示它正在消耗大约 350MB memory dashboard IMG url

为什么会这样?它迫使我使用 F2 实例;如果我降级到 F1,它会一直失败并重新启动。

我注意到,一旦我将我的 cronjob 从每 30 分钟运行一次更改为每 2 分钟运行一次,他们开始在前端实例中每天向我收取 40 小时的费用,这大约是 16 小时前的更改,而我只有 1 个实例在运行.这怎么可能? instance count img url

谢谢

【问题讨论】:

  • 两种环境下的JVM参数是什么?
  • @tgdavies 在我的 app.yml 文件中:运行时:java11 入口点:java -Xms64M -Xmx256M -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:+PrintCommandLineFlags -jar myjar.jar。在我的本地,我没有设置在我的 Eclipse IDE 上运行的任何 JVM 参数。
  • 首先,从操作系统的角度来看,total-free 并不能准确衡量 JVM 正在使用多少内存,这可能是 GAE 所报告的。空闲堆内存仍分配给 JVM,其他应用程序无法使用。您应该查看本地 JVM 进程正在使用的总内存。

标签: java spring-boot google-app-engine google-cloud-platform


【解决方案1】:

您看到这些差异的原因是 Cloud Console 显示了适用于实例的内存限制的 JVM 进程的实际大小(包括堆栈帧、永久生成空间、直接缓冲区、机器代码等)指的是JVM堆。运行时使用了一些堆内存,这些内存会计入应用的总堆使用量。

现在,重要的是要了解这些方法的作用以及如何计算要分配的可用内存:

totalMemory()

JVM 当前使用的所有内存。它通常低于 maxMemory 因为 JVM 是懒惰分配内存的,“懒惰”的意思是一些内存 最初分配并使用,并且,如果一个新的内存块是 需要,完成另一个分配,直到所有可用内存 (maxMemory())。


ma​​xMemory():

最大可用堆内存(实例大小仅限于此 值)。


freeMemory():

当前由 JVM 分配但未使用的内存部分。


可分配的“实际总内存”为:

rt.freeMemory() + (rt.maxMemory() - rt.totalMemory())

因此可用内存可能比rt.freeMemory() 的输出多。

【讨论】:

    猜你喜欢
    • 2015-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-24
    • 2019-07-26
    • 2012-05-06
    • 2022-12-09
    • 2012-07-08
    相关资源
    最近更新 更多