简体   繁体   English

Java 和 PHP 应用程序的 GC 和内存行为?

[英]GC and memory behaviour for Java and PHP app?

This question is regarding the Garbage collection behavior when request need more memory than allocated to Pod .这个问题是关于当请求需要比分配给 Pod 更多的内存时的垃圾收集行为。 If GC is not able to free memory, will it continue to run GC continuously or throw out of memory.如果 GC 无法释放内存,它会继续运行 GC 还是抛出内存不足。

One pod contains java based app and another contain PHP based.一个 pod 包含基于 Java 的应用程序,另一个包含基于 PHP 的应用程序。 In case of java xmx value is same as given to pod limit.在 java xmx 的情况下,值与给定 pod 限制相同。

I can only talk about Java GC.我只能谈谈Java GC。 (PHP's GC behavior will be different.) (PHP 的 GC 行为会有所不同。)

If GC is not able to free memory, will it continue to run GC continuously after regular interval or throw out of memory.如果 GC 无法释放内存,它会在定期间隔后继续运行 GC 还是抛出内存。

It depends on the JVM options.这取决于 JVM 选项。

A JVM starts with an initial size for the heap and will expand it as required. JVM 以堆的初始大小开始,并将根据需要扩展它。 However, it will only expand the heap up to a fixed maximum size.但是,它只会将堆扩展到固定的最大大小。 That maximum size is determined when the JVM starts from either an option ( -Xmx ) or default heap size rules.当 JVM 从选项 ( -Xmx ) 或默认堆大小规则启动时,将确定该最大大小。 It can't be changed after startup.启动后无法更改。

As the heap space used gets close to the limit, the GC is likely to occur more and more frequently.随着使用的堆空间接近极限,GC 可能会越来越频繁地发生。 The default behavior on a modern JVM is to monitor the %time spent doing garbage collection.现代 JVM 上的默认行为是监控用于垃圾收集的时间百分比。 If it exceeds a (configurable) threshold, then you will get an OOME with a message about the GC Overhead Threshold having been exceeded.如果它超过(可配置的)阈值,那么您将收到一条 OOME,其中包含一条关于已超出 GC 开销阈值的消息。 This can happen even if there is enough space to "limp along" for a bit longer.即使有足够的空间“跛行”一段时间,这种情况也可能发生。

You can turn off the GC Overhead Limit stuff, but it is inadvisable.您可以关闭 GC Overhead Limit 的东西,但这是不可取的。

The JVM will also throw an OOME if it simply doesn't have enough heap space after doing a full garbage collection.如果 JVM执行完整的垃圾回收没有足够的堆空间它也会抛出 OOME。

Finally, a JVM will throw an OOME if it tries to grow the heap and the OS refuses to give it the memory it requested.最后,如果 JVM 尝试增大堆并且操作系统拒绝为其提供所需的内存,则会抛出 OOME。 This could happen because:这可能是因为:

  • the OS has run out of RAM操作系统已用完 RAM
  • the OS has run out of swap space操作系统已用完交换空间
  • the process has exceeded a ulimit , or进程已超过ulimit ,或
  • the process group (container) has exceeded a container limit.进程组(容器)已超出容器限制。

The JVM is only marginally aware of the memory available in its environment. JVM 仅略微了解其环境中可用的内存。 On a bare metal OS or a VM under a hypervisor, the default heap size depends on the amount of RAM.在裸机操作系统或虚拟机管理程序下的 VM 上,默认堆大小取决于 RAM 量。 On a bare metal OS, that is physical RAM.在裸机操作系统上,这是物理 RAM。 On a VM, it will be ... what ever the guest OS sees as its physical memory.在虚拟机上,它将是......来宾操作系统将其视为其物理内存的内容。

With Kubernetes, the memory available to an application is likely to be further limited by cgroups or similar.使用 Kubernetes,应用程序可用的内存可能会受到 cgroup 或类似物的进一步限制。 I understand that recent Java releases have tweaks that make them more suitable for running in containers.我知道最近的 Java 版本进行了一些调整,使它们更适合在容器中运行。 I think this means that they can use the cgroup memory limits rather than the physical memory size when calculating a default heap size.我认为这意味着在计算默认堆大小时,他们可以使用 cgroup 内存限制而不是物理内存大小。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM