java - GAE 使用的内存比我的 Java 应用程序多得多
问题描述
我有一个在 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 内存仪表板 IMG url
为什么会这样?它迫使我使用 F2 实例;如果我降级到 F1,它会一直失败并重新启动。
我注意到,一旦我将我的 cronjob 从每 30 分钟运行一次更改为每 2 分钟运行一次,他们开始在前端实例中每天向我收取 40 小时的费用,大约是在此更改之前 16 小时,而我只有 1 个实例正在运行。这怎么可能? 实例计数 img url
谢谢
解决方案
您看到这些差异的原因是 Cloud Console 显示了 JVM 进程的实际大小(包括堆栈帧、永久生成空间、直接缓冲区、机器代码等),其中适用于实例的内存限制是指JVM 堆。运行时使用一些堆内存,这些内存会计入应用程序的总堆使用量。
现在,重要的是要了解这些方法的作用以及如何计算要分配的可用内存:
总内存():
JVM 当前使用的所有内存。它通常低于 maxMemory,因为 JVM 会延迟分配内存,“延迟”意味着最初分配并使用了一些内存,如果需要新的内存块,则会完成另一次分配,直至所有可用内存 (
maxMemory()
)。
最大内存():
最大可用堆内存(实例大小限于此值)。
空闲内存():
当前由 JVM 分配但未使用的内存部分。
可以分配的“实际总内存”为:
rt.freeMemory() + (rt.maxMemory() - rt.totalMemory())
所以可以有比输出更多的可用内存rt.freeMemory()
。
推荐阅读
- c# - 为什么 IsGenericTypeDefinition 返回 false?
- javascript - Bootstrap-Multiselect 上的 jQuery 动画效果
- firebase - 用户或应用程序的 Firebase Rest Api 设置语言?
- php - 通过 curl 从外部网站向动作控制器发送数据时设置会话
- jackson - 多个 POJO 的 Json Java 数据绑定
- sql - Oracle 到 T-SQL CTE 转换错误
- vba - 将不同 Excel 中的数据复制到同一个文件夹中
- asp.net - 在 .NET 4.7.2 下使用 VB.NET 在 WebForms 中注入构造函数
- powerbuilder - Powerbuilder - 尝试使用单个双引号 (") 导入长字符串
- azure - AKS 添加非 Azure 节点