我在docker容器中运行我的java应用程序。我使用AWS Beanstalk。 docker基础映像是CentOS。我在EC2实例上运行一个容器,在Amazon Linux AMI上为Beanstalk提供4GB的RAM。
我应该如何配置容器和JVM内存设置。 现在我有:
在Amazon Linux Beanstalk AMI ec2实例上4GB
我将3GB的4个用作泊坞容器
{
"AWSEBDockerrunVersion": 2,
"Authentication": {
"Bucket": "elasticbeanstalk-us-east-1-XXXXXX",
"Key": "dockercfg"
},
"containerDefinitions": [
{
"name": "my-service",
"image": "docker-registry:/myapp1.0.2",
"essential": true,
"memory": 3184,
"portMappings": [
{
"hostPort": 80,
"containerPort": 8080
}
]
}
}
JVM设置
-Xms2560m
-Xmx2560m
-XX:+UseConcMarkSweepGC
-XX:+CMSParallelRemarkEnabled
-XX:+UseCMSInitiatingOccupancyOnly
-XX:CMSInitiatingOccupancyFraction=70
-XX:+ScavengeBeforeFullGC
-XX:+CMSScavengeBeforeRemark
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=./heapdump.hprof
我可以将整个ec2实例内存专用于docker容器4gb,并将JVM设置为4GB吗?
我认为当JVM无法分配Xmx内存参数时,JVM可能会崩溃。如果是这样,我可以用于容器和JVM的最佳值是多少?
现在我为Amazon linux本身留下了1GB的余量,为容器中的CentOS留下了512MB的余量。 1.5GB wasted
。可以做得更好吗?
答案 0 :(得分:1)
真正的答案非常依赖于您的Java应用程序和使用情况。
从3.5G的JVM堆开始
将容器最大值设置为3.8G以覆盖java
的开销
反复进行负载测试。
-Xmx
和-Xms
仅控制Java's heap size,因此您无法将所有可用内存分配给Java堆,并期望java和系统的其余部分运行良好(或根本)。
您还需要满足:
堆栈:-Xss
*线程数(Xss默认为64位上的1MB)
PermGen / Metaspace:-XX:MaxPermSize
默认为64MB。元空间为21MB,但这可以增长。
您的应用程序也可以使用大量共享内存,在堆外部执行JNI操作,依赖大型mmaped文件来获得性能或exec
外部二进制文件或堆外的任何其他奇怪内容。在您选择的内存级别进行一些负载测试,然后高于和低于这些级别,以确保您不会遇到或接近任何影响性能的内存问题。
Centos没有"运行"在容器中,docker只为您的JVM进程提供文件系统映像以供参考。通常你不会跑#34;不只是该容器中的java
进程。
当你在一个只有一个容器的专用主机上时限制容器最大内存并没有什么好处,但它也不会受到伤害,以防本机java中的某些内容随之丢失有效内存。
这里的内存开销需要满足上面提到的可能的本机Java用法以及将从容器映像(而不是主机)加载并缓存的jre的额外系统文件。当你达到容器内存限制时,你也不会获得好的堆栈或堆转换。
普通的亚马逊AMI只需要运行大约50-60MB的内存加上文件缓存的一些备用,所以说256MB可以为操作系统提供一些余地。