如何重用容器弹出丢弃的资源

最近和阿里的一些同事聊到用Docker部署Java应用。其中一个常见的问题是如何在容器中设置JVM的内存限制。

如果使用官方的Java映像或者基于Java映像的Docker映像,那么通过传递JAVA_OPTS环境变量就可以很容易地设置JVM的内存参数。例如,对于正式的tomcat映像,我们可以执行下面的命令来启动一个最大内存为512M的Tomcat实例。

docker run-RM-e JAVA _ OPTS = '-xmx 512m ' Tomcat:8

在日志中我们可以清楚的发现设置已经生效“命令行参数:-xmx512m”。

自动堆集

源代码可以从Github获得。它基于Docker的官方Tomcat镜像,它的启动脚本会检查CGroup中的内存限制,并计算JVM传递给Tomcat的最大堆大小。它的代码如下

#!/bin/bash

limit _ in _ bytes = $(cat/sys/fs/cgroup/memory/memory/denverdino/Tomcat:8-自动堆

通过下面的命令,我们可以从日志中检测到相应的JVM参数已经被设置为448MB (512-64)。

docker日志测试

...

02-Apr-2016 14:18:09.870 INFO[main]org . Apache . catalina . startup . version logger listener . log命令行参数:-Xmx448m

...

我们还可以方便地调整Java应用程序的内存。

Docker 1.10提供了动态修改容器资源限制的能力。但是,因为JVM不能感知容器资源的修改,所以我们仍然需要重新启动tomcat来更改JVM的内存设置。例如,我们可以通过以下命令将容器内存限制调整为1GB。

docker更新-m 1024m测试

码头工人重启试验

再次检查日志,相应的最大JVM堆大小已经设置为960MB。

docker日志测试

...

02-Apr-2016 14:21:07.644 INFO[main]org . Apache . catalina . startup . version logger listener . log命令行参数:-Xmx960m