GAE使用的内存比我的Java应用程序多得多

GAE使用的内存比我的Java应用程序多得多,java,spring-boot,google-app-engine,google-cloud-platform,Java,Spring Boot,Google App Engine,Google Cloud Platform,我有一个Java应用程序(SpringBoot)在Google应用程序引擎上运行;然而,我看到了我的Java应用程序内存消耗和GAE显示的仪表板之间的奇怪差异 在我使用VisualVM的本地机器中,我可以看到它即使在峰值时间也不会消耗超过100MB的内存,我添加了一个servlet来返回所使用的内存量: @GetMapping(“/”) 公共字符串索引(){ Runtime rt=Runtime.getRuntime(); 长总计=rt.totalMemory(); long free=rt.f

我有一个Java应用程序(SpringBoot)在Google应用程序引擎上运行;然而,我看到了我的Java应用程序内存消耗和GAE显示的仪表板之间的奇怪差异

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

@GetMapping(“/”)
公共字符串索引(){
Runtime rt=Runtime.getRuntime();
长总计=rt.totalMemory();
long free=rt.freemory();
长期使用=完全免费;
返回“总计:+Total/1024/1024+”MB
已使用:+Used/1024/1024+”MB
空闲:+Free/1024/1024+“MB”; }
我现在在GAE中部署的应用程序返回:

Total: 91MB
Used: 69MB
Free: 21MB
与此同时,GAE仪表板显示它消耗了大约350MB的内存

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

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


谢谢

您看到这些差异的原因是云控制台显示JVM进程的实际大小(包括堆栈帧、perm gen空间、直接缓冲区、机器代码等),其中应用于实例的内存限制指的是JVM堆。运行时使用一些堆内存,这些内存根据应用程序的总堆使用量计算

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

totalMemory()

JVM当前使用的所有内存。它通常低于maxMemory 因为JVM延迟分配内存,“延迟”意味着一些内存 初始分配并使用,并且,如果需要新的内存块 如果需要,则进行另一次分配,直到所有可用内存 (
maxMemory()


maxMemory():

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


freemory():

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


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

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

因此,可以有比
rt.freemory()

的输出更多的可用内存这两个环境中的JVM参数是什么?@tgdavies on my app.yml文件:runtime:java11 entrypoint:java-Xms64M-Xmx256M-XX:+UseG1GC-XX:+ParallelRefProcEnabled-XX:+PrintCommandLineFlags-jar.jar。首先,从操作系统的角度来看,total-free并不是JVM使用多少内存的准确度量,这可能是GAE报告的内容。空闲堆内存仍分配给JVM,其他应用程序无法使用。您应该查看本地JVM进程正在使用的总内存。