JVM和Docker默认设置中的陷阱
以下是JVM中Docker默认设置之间的一些常见陷阱。
首先,有很多关于JVM和容器意识的文章:
在本文中,我使用Java 11,这意味着垃圾收集器的默认值应该是G1GC! 让我们看一下默认值,JVM会根据内存大小和提供的CPU自动选择这些默认值。
基于Docker CPU的默认GC
$ docker run --cpus="2" openjdk:11-jre java -XX:+PrintFlagsFinal -version | grep -E "(MAX|UseSerialGC|UseG1GC|MaxHeapSize)"
size_t MaxHeapSize = 5200936960 {product} {ergonomic}
bool UseG1GC = true {product} {ergonomic}
bool UseSerialGC = false {product} {default}
$ docker run --cpus="1" openjdk:11-jre java -XX:+PrintFlagsFinal -version | grep -E "(MAX|UseSerialGC|UseG1GC|MaxHeapSize)"
size_t MaxHeapSize = 5200936960 {product} {ergonomic}
bool UseG1GC = false {product} {default}
bool UseSerialGC = true {product} {ergonomic}
注意你的Docker容器中的CPU数量; 垃圾收集器的类型可以完全不同。
基于Docker内存的默认GC
$ docker run -m 2g openjdk:11-jre java -XX:+PrintFlagsFinal -version | grep -E "(MAX|UseSerialGC|UseG1GC|MaxHeapSize)"
size_t MaxHeapSize = 536870912 {product} {ergonomic}
bool UseG1GC = true {product} {ergonomic}
bool UseSerialGC = false {product} {default}
$ docker run -m 1g openjdk:11-jre java -XX:+PrintFlagsFinal -version | grep -E "(MAX|UseSerialGC|UseG1GC|MaxHeapSize)"
size_t MaxHeapSize = 268435456 {product} {ergonomic}
bool UseG1GC = false {product} {default}
bool UseSerialGC = true {product} {ergonomic}
在上面的代码片段中,JVM根据提供的内存大小自动更改了默认垃圾回收器。
默认堆大小始终是可用内存的1/4!
$ docker run -m 512m openjdk:11-jre java -XX:+PrintFlagsFinal -version | grep -E "(MAX|UseSerialGC|UseG1GC|MaxHeapSize)"
size_t MaxHeapSize = 134217728 {product} {ergonomic}
bool UseG1GC = false {product} {default}
bool UseSerialGC = true {product} {ergonomic}
$ docker run -m 256m openjdk:11-jre java -XX:+PrintFlagsFinal -version | grep -E "(MAX|UseSerialGC|UseG1GC|MaxHeapSize)"
size_t MaxHeapSize = 132120576 {product} {ergonomic}
bool UseG1GC = false {product} {default}
bool UseSerialGC = true {product} {ergonomic}
JVM从一定数量的内存中停止选择堆大小的1/4,并开始使比率越来越小,以为你的应用程序提供更大的堆内存。
为什么选择SerialGC?
$ docker run -m 1g openjdk:11-jre java -XX:+PrintFlagsFinal -version | grep -E "(MAX|UseSerialGC|UseG1GC|MaxHeapSize)"
size_t MaxHeapSize = 268435456 {product} {ergonomic}
bool UseG1GC = false {product} {default}
bool UseSerialGC = true {product} {ergonomic}
$ docker run -m 1g openjdk:11-jre java -Xmx700m -XX:+PrintFlagsFinal -version | grep -E "(MAX|UseSerialGC|UseG1GC|MaxHeapSize)"
size_t MaxHeapSize = 734003200 {product} {command line}
bool UseG1GC = false {product} {default}
bool UseSerialGC = true {product} {ergonomic}
这很奇怪,根据上面的示例,我们仍然应该将G1GC作为默认值,但是知道我们可以注意到JVM选择了SerialGC。 一讲,你总是必须尝试一下JVM选择了哪些默认值,并考虑它是否合理并适合你。 你会注意到JVM定义的参数被标记为符合人体工程学的JVM选项。
> 喜欢这篇文章的可以点个赞,欢迎大家留言评论,记得关注我,每天持续更新技术干货、职场趣事、海量面试资料等等
> 如果你对java技术很感兴趣也可以交流学习,共同学习进步。
> 不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代
文章写道这里,欢迎完善交流。最后奉上近期整理出来的一套完整的java架构思维导图,分享给大家对照知识点参考学习。有更多JVM、Mysql、Tomcat、Spring Boot、Spring Cloud、Zookeeper、Kafka、RabbitMQ、RockerMQ、Redis、ELK、Git等Java干货
- tomcat7吗默认JVM设置
- Eclipse、IDEA环境下设置jvm默认编码
- Eclipse、IDEA环境下设置jvm默认编码
- JSF2 设置(当前JVM)默认时区
- Eclipse、IDEA环境下设置jvm默认编码
- docker默认设置下访问私有docker hub遇到的https问题
- 设置ubuntu默认中文字符
- JVM 内存设置大小(Xms Xmx PermSize MaxPermSize 区别)
- 谈谈Tomcat默认应用设置的问题
- eclipse 设置默认编码为Utf-8
- 设置WebSphere的默认编码
- Apache中如何设置网站默认首页?
- UI控件 UISwitch 设置默认为开,添加事件
- Android framework系统默认设置修改
- IE:设置默认电子邮件
- Csharp: TreeView 初始化设置默认选择节点
- MyEclipse8.5 默认工作空间的设置
- 设置python的默认编码为utf8
- MyEclipse 设置JSP的默认打开方式
- 修改docker镜像默认目录