应用办公生活信息教育商业
投稿投诉
商业财经
汽车智能
教育国际
房产环球
信息数码
热点科技
生活手机
晨报新闻
办公软件
科学动态
应用生物
体育时事

Java和Docker限制的那些事儿

  虚拟化中的不匹配
  Java和Docker的结合并不是完美匹配的,最初的时候离完美匹配有相当大的距离。对于初学者来说,JVM的全部设想就是,虚拟机可以让程序与底层硬件无关。
  那么,把我们的Java应用打包到JVM中,然后整个再塞进Docker容器中,能给我们带来什么好处呢?大多数情况下,你只是在复制JVMs和Linux容器,除了浪费更多的内存,没任何好处。感觉这样子挺傻的。
  不过,Docker可以把你的程序,设置,特定的JDK,Linux设置和应用服务器,还有其他工具打包在一起,当做一个东西。站在DevOpsCloud的角度来看,这样一个完整的容器有着更高层次的封装。问题一:内存
  时至今日,绝大多数产品级应用仍然在使用Java8(或者更旧的版本),而这可能会带来问题。Java8(update131之前的版本)跟Docker无法很好地一起工作。问题是在你的机器上,JVM的可用内存和CPU数量并不是Docker允许你使用的可用内存和CPU数量。
  比如,如果你限制了你的Docker容器只能使用100MB内存,但是呢,旧版本的Java并不能识别这个限制。Java看不到这个限制。JVM会要求更多内存,而且远超这个限制。如果使用太多内存,Docker将采取行动并杀死容器内的进程!JAVA进程被干掉了,很明显,这并不是我们想要的。
  为了解决这个问题,你需要给Java指定一个最大内存限制。在旧版本的Java(8u131之前),你需要在容器中通过设置Xmx来限制堆大小。这感觉不太对,你可不想定义这些限制两次,也不太想在你的容器中来定义。
  幸运的是我们现在有了更好的方式来解决这个问题。从Java9之后(8u131),JVM增加了如下标志:XX:UnlockExperimentalVMOptionsXX:UseCGroupMemoryLimitForHeap
  这些标志强制JVM检查Linux的cgroup配置,Docker是通过cgroup来实现最大内存设置的。现在,如果你的应用到达了Docker设置的限制(比如500MB),JVM是可以看到这个限制的。JVM将会尝试GC操作。如果仍然超过内存限制,JVM就会做它该做的事情,抛出OutOfMemoryException。也就是说,JVM能够看到Docker的这些设置。
  从Java10之后(参考下面的测试),这些体验标志位是默认开启的,也可以使用XX:UseContainerSupport来使能(你可以通过设置XX:UseContainerSupport来禁止这些行为)。问题二:CPU
  第二个问题是类似的,但它与CPU有关。简而言之,JVM将查看硬件并检测CPU的数量。它会优化你的runtime以使用这些CPUs。但是同样的情况,这里还有另一个不匹配,Docker可能不允许你使用所有这些CPUs。可惜的是,这在Java8或Java9中并没有修复,但是在Java10中得到了解决。
  从Java10开始,可用的CPUs的计算将采用以不同的方式(默认情况下)解决此问题(同样是通过UseContainerSupport)。Java和Docker的内存处理测试
  作为一个有趣的练习,让我们验证并测试Docker如何使用几个不同的JVM版本标志甚至不同的JVM来处理内存不足。
  首先,我们创建一个测试应用程序,它只是简单地吃内存并且不释放它。javaimportjava。util。ArrayList;importjava。util。List;publicclassMemEat{publicstaticvoidmain(String〔〕args){ListlnewArrayList();while(true){byteb〔〕newbyte〔1048576〕;l。add(b);RuntimertRuntime。getRuntime();System。out。println(freememory:rt。freeMemory());}}}
  我们可以启动Docker容器并运行这个应用程序来查看会发生什么。测试一:Java8u111
  首先,我们将从具有旧版本Java8的容器开始(update111)。shelldockerrunm100mitjava:openjdk8u111binbash
  我们编译并运行MemEat。java文件:shelljavacMemEat。javajavaMemEat。。。freememory:67194416freememory:66145824freememory:65097232Killed
  正如所料,Docker已经杀死了我们的Java进程。不是我们想要的(!)。你也可以看到输出,Java认为它仍然有大量的内存需要分配。
  我们可以通过使用Xmx标志为Java提供最大内存来解决此问题:shelljavacMemEat。javajavaXmx100mMemEat。。。freememory:1155664freememory:1679936freememory:2204208freememory:1315752Exceptioninthreadmainjava。lang。OutOfMemoryError:JavaheapspaceatMemEat。main(MemEat。java:8)
  在提供了我们自己的内存限制之后,进程正常停止,JVM理解它正在运行的限制。然而,问题在于你现在将这些内存限制设置了两次,Docker一次,JVM一次。测试二:Java8u144
  如前所述,随着增加新标志来修复问题,JVM现在可以遵循Docker所提供的设置。我们可以使用版本新一点的JVM来测试它。shelldockerrunm100mitadoptopenjdkopenjdk8binbash
  (在撰写本文时,此OpenJDKJava镜像的版本是Java8u144)
  接下来,我们再次编译并运行MemEat。java文件,不带任何标志:shelljavacMemEat。javajavaMemEat。。。freememory:67194416freememory:66145824freememory:65097232Killed
  依然存在同样的问题。但是我们现在可以提供上面提到的实验性标志来试试看:shelljavacMemEat。javajavaXX:UnlockExperimentalVMOptionsXX:UseCGroupMemoryLimitForHeapMemEat。。。freememory:1679936freememory:2204208freememory:1155616freememory:1155600Exceptioninthreadmainjava。lang。OutOfMemoryError:JavaheapspaceatMemEat。main(MemEat。java:8)
  这一次我们没有告诉JVM限制的是什么,我们只是告诉JVM去检查正确的限制设置!现在感觉好多了。测试三:Java10u23
  有些人在评论和Reddit上提到Java10通过使实验标志成为新的默认值来解决所有问题。这种行为可以通过禁用此标志来关闭:XX:UseContainerSupport。
  当我测试它时,它最初不起作用。在撰写本文时,AdoptAJDKOpenJDK10镜像与jdk1023一起打包。这个JVM显然还是不理解UseContainerSupport标志,该进程仍然被Docker杀死。shelldockerrunm100mitadoptopenjdkopenjdk10binbash
  测试了代码(甚至手动提供需要的标志):shelljavacMemEat。javajavaMemEat。。。freememory:96262112freememory:94164960freememory:92067808freememory:89970656KilledjavaXX:UseContainerSupportMemEatUnrecognizedVMoptionUseContainerSupportError:CouldnotcreatetheJavaVirtualMachine。Error:Afatalexceptionhasoccurred。Programwillexit。
  测试四:Java10u46(Nightly)
  我决定尝试AdoptAJDKOpenJDK10的最新nightly构建。它包含的版本是Java1046,而不是Java1023。shelldockerrunm100mitadoptopenjdkopenjdk10:nightlybinbash
  然而,在这个ngithly构建中有一个问题,导出的PATH指向旧的Java1023目录,而不是1046,我们需要修复这个问题。shellexportPATHPATH:optjavaopenjdkjdk1046binjavacMemEat。javajavaMemEat。。。freememory:3566824freememory:2796008freememory:1480320Exceptioninthreadmainjava。lang。OutOfMemoryError:JavaheapspaceatMemEat。main(MemEat。java:8)
  成功!不提供任何标志,Java10依然可以正确检测到Dockers内存限制。测试五:OpenJ9
  我最近也在试用OpenJ9,这个免费的替代JVM已经从IBMJ9开源,现在由Eclipse维护。
  请在我的下一篇博文中阅读关于OpenJ9的更多信息。
  它运行速度快,内存管理非常好,性能卓越,经常可以为我们的微服务节省多达3050的内存。这几乎可以将SpringBoot应用程序定义为micro了,其运行时间只有100200mb,而不是300mb。我打算尽快就此写一篇关于这方面的文章。
  但令我惊讶的是,OpenJ9还没有类似于Java8910中针对cgroup内存限制的标志(backported)的选项。如果我们将以前的测试用例应用到最新的AdoptAJDKOpenJDK9OpenJ9build:shelldockerrunm100mitadoptopenjdkopenjdk9openj9binbash
  我们添加OpenJDK标志(OpenJ9会忽略的标志):shelljavaXX:UnlockExperimentalVMOptionsXX:UseCGroupMemoryLimitForHeapMemEat。。。freememory:83988984freememory:82940400freememory:81891816Killed
  Oops,JVM再次被Docker杀死。
  我真的希望类似的选项将很快添加到OpenJ9中,因为我希望在生产环境中运行这个选项,而不必指定最大内存两次。EclipseIBM正在努力修复这个问题,已经提了issues,甚至已经针对issues提交了PR。更新:(不推荐Hack)
  一个稍微丑陋hacky的方式来解决这个问题是使用下面的组合标志:shelljavaXmxcatsysfscgroupmemorymemory。limitinbytesMemEat。。。freememory:3171536freememory:2127048freememory:2397632freememory:1344952JVMDUMP039IProcessingdumpeventsysthrow,detailjavalangOutOfMemoryErrorat2018051514:04:26pleasewait。JVMDUMP032IJVMrequestedSystemdumpusingcore。20180515。140426。125。0001。dmpinresponsetoaneventJVMDUMP010ISystemdumpwrittentocore。20180515。140426。125。0001。dmpJVMDUMP032IJVMrequestedHeapdumpusingheapdump。20180515。140426。125。0002。phdinresponsetoaneventJVMDUMP010IHeapdumpwrittentoheapdump。20180515。140426。125。0002。phdJVMDUMP032IJVMrequestedJavadumpusingjavacore。20180515。140426。125。0003。txtinresponsetoaneventJVMDUMP010IJavadumpwrittentojavacore。20180515。140426。125。0003。txtJVMDUMP032IJVMrequestedSnapdumpusingSnap。20180515。140426。125。0004。trcinresponsetoaneventJVMDUMP010ISnapdumpwrittentoSnap。20180515。140426。125。0004。trcJVMDUMP013IProcesseddumpeventsysthrow,detailjavalangOutOfMemoryError。Exceptioninthreadmainjava。lang。OutOfMemoryError:JavaheapspaceatMemEat。main(MemEat。java:8)
  在这种情况下,堆大小受限于分配给Docker实例的内存,这适用于较旧的JVM和OpenJ9。这当然是错误的,因为容器本身和堆外的JVM的其他部分也使用内存。但它似乎工作,显然Docker在这种情况下是宽松的。也许某些bash大神会做出更好的版本,从其他进程的字节中减去一部分。
  无论如何,不要这样做,它可能无法正常工作。测试六:OpenJ9(Nightly)
  有人建议使用OpenJ9的最新nightly版本。shelldockerrunm100mitadoptopenjdkopenjdk9openj9:nightlybinbash
  最新的OpenJ9夜间版本,它有两个东西:另一个有问题的PATH参数,需要先解决这个问题JVM支持新标志UseContainerSupport(就像Java10一样)
  shellexportPATHPATH:optjavaopenjdkjdk9。0。412binjavacMemEat。javajavaXX:UseContainerSupportMemEat。。。freememory:5864464freememory:4815880freememory:3443712freememory:2391032JVMDUMP039IProcessingdumpeventsysthrow,detailjavalangOutOfMemoryErrorat2018051521:32:07pleasewait。JVMDUMP032IJVMrequestedSystemdumpusingcore。20180515。213207。62。0001。dmpinresponsetoaneventJVMDUMP010ISystemdumpwrittentocore。20180515。213207。62。0001。dmpJVMDUMP032IJVMrequestedHeapdumpusingheapdump。20180515。213207。62。0002。phdinresponsetoaneventJVMDUMP010IHeapdumpwrittentoheapdump。20180515。213207。62。0002。phdJVMDUMP032IJVMrequestedJavadumpusingjavacore。20180515。213207。62。0003。txtinresponsetoaneventJVMDUMP010IJavadumpwrittentojavacore。20180515。213207。62。0003。txtJVMDUMP032IJVMrequestedSnapdumpusingSnap。20180515。213207。62。0004。trcinresponsetoaneventJVMDUMP010ISnapdumpwrittentoSnap。20180515。213207。62。0004。trcJVMDUMP013IProcesseddumpeventsysthrow,detailjavalangOutOfMemoryError。Exceptioninthreadmainjava。lang。OutOfMemoryError:Javaheapspace
  TADAAA,正在修复中!
  奇怪的是,这个标志在OpenJ9中默认没有启用,就像它在Java10中一样。再说一次:确保你测试了这是你想在一个Docker容器中运行Java。结论
  简言之:注意资源限制的不匹配。测试你的内存设置和JVM标志,不要假设任何东西。
  如果您在Docker容器中运行Java,请确保你设置了Docker内存限制和在JVM中也做了限制,或者你的JVM能够理解这些限制。
  如果您无法升级您的Java版本,请使用Xmx设置您自己的限制。
  对于Java8和Java9,请更新到最新版本并使用:XX:UnlockExperimentalVMOptionsXX:UseCGroupMemoryLimitForHeap
  对于Java10,确保它支持UseContainerSupport(更新到最新版本)。
  对于OpenJ9(我强烈建议使用,可以在生产环境中有效减少内存占用量),现在使用Xmx设置限制,但很快会出现一个支持UseContainerSupport标志的版本。
  小伙伴们有兴趣想了解更多相关学习资料请点赞收藏评论转发关注我之后私信我,注意回复【111】即可获取更多免费资料!!!

NBA公布附加赛赛程虽然常规赛具体排名尚未确定,但东部参加附加赛的四支球队已经确定,分别是骑士、篮网、老鹰和黄蜂。而在西部,快船、鹈鹕、马刺已经确定要通过附加赛竞争一个季后赛席位,森林狼理论上还有……印度科学家研发出低接触电阻的2D金属半导体接口来源:内容来自Swarajya,谢谢。印度科学家通过计算设计出了一种低接触电阻的金属半导体接口,该接口带有2D单分子层,用于下一代晶体管,可以提高设备性能。石墨烯是……手机子品牌盘点,哪家更强商场如战场,如今的手机市场可谓是百家争鸣,各领风骚,但在手机同质化(一个模具出多款手机)严重的今天,如何保证自家产品的差异化呢?于是各家厂商纷纷开始设立自己的子品牌,并且给予全……互联网教父张朝阳人一旦出名,就不再需要婚姻赶上了互联网宇宙的第一次爆炸,张朝阳一举成为21世纪初中国互联网头号人物,45岁前,他名利双收。当世俗的一切欲望都得到满足,张朝阳呈现出一种无需辩驳的自信状态。社交……喜欢吃面条的要收藏,教你7种懒人做法,汤鲜味美,一周7天不重北方面条,南方米饭一句话概括了地方的主食特色,说起面条,很多人百吃不厌,相比于其他的食物,面条最为素净,可以衬托任何食物。相比于其他的食物,面条最为素净,可以衬托任何食物。喜欢……每天几道题,温故知新今天学习的是关于嫦娥和嫦娥一号三道题目的记忆方法。题目中有提到探月和绕月的,答案都选嫦娥或者嫦娥一号,都直接选嫦娥。我觉得不记位置反而比记位置简单好选了。我国的探月……新疆那么大,我想去走走上海的疫情发展的如此凶猛快速,是每一个人没有想象到的,作为一个50后的老人尽可能的不给社区添麻烦,疫情初期,还给社区做做志愿者,维护一下小区日常管理,配合抗疫医生指导居民正常二……日本大阪最有魅力的地区是哪里?有人说想看日本大阪居住地相关排行榜,这不就来了吗。美食之街、搞笑之街,这就是很多人都知道的日本大阪府。自古以来,大阪府就作为日本的商业中心而繁荣起来,以各种美食为代表,大阪府有……2022最新Python学习路线,学完即可进大厂技术日新月异,对于初入职场的同学来说,经常会困惑该往哪个方向发展,这一点相信每个人都是深有体会的。相信最近小伙伴一定刷到了很多关于Python的学习教程,但是很多时候我们……璀璨灯火遇上冬奥,京城醉美夜景不容错过,这份北京超全元宵灯会刚刚度过春节小长假的我们想要玩乐的心似乎还没有收回来一元复始,元宵节的脚步越来越近赶紧抓住年的尾巴出去浪!俗话说正月十五闹元宵北京的花灯会也开始筹……建议中老年人少吃猪牛羊肉,多吃这3样,身体强壮少生病给中老年人的建议:如果不缺钱,少吃猪牛羊肉,多吃这3样,身体强壮少生病。哈喽,大家好,今天又到了和大家分享美食的时刻了,你准备好了吗?随着疫情的不断重复,实际上价格已经上……霍华德詹姆斯总是在看数据他以此记录场上的一举一动ampamp直播吧6月30日讯近日,湖人球员霍华德参加了一档播客,谈到了詹姆斯。霍华德说:他总是会看数据。并不是说他想要刷数据,他只是希望通过数据来弄清楚如何打得更高效。‘我们应该让……
湖人马刺大交易,场均三双不请自来,波波维奇爱徒辅佐詹皇交易截止日越来越近,交易传闻开始泛滥,ESPN记者最近谈到了马刺这支球队,马刺夺冠那一套体系已经过时了,马刺必须尽快重建建立新的体系,言外之意就是,波波维奇的体系已经在这个时代……夏至饮茶,这4件事一定要注意图源网络,侵权删夏天天气热,很多人都喜欢喝茶解暑,今天就跟大家讲讲夏季喝茶的注意事项。一:忌饮浓茶夏季提神,很多人喜欢喝浓茶,但是浓茶在人体内的滞留时间长,会……重磅独家旭辉集团组织大调整(最新)大家好,我是地产一品堂。地产行业风云变幻,地产行业持续下行,2022年开年到现在各种组织构架调整,变相花式裁员等操作着实让人有点上头。多家房企再掀浪潮,包括融创、建……危机升级,美国衰退!中国能否抛售美债?让美国陷入危机?有人想过一个问题:当美国大幅加息,甚至缩表的时候,会出现经济衰退,甚至经济危机。这个时候,中国可否趁机抛售美债?让美国的经济变得更惨?从而出一口恶气?中国能否抛售美……仲夏夜之梦,绣球花带来的浪漫,北京赏花指南翻看去年的照片,突然发现在陶然亭公园拍到了绣球花,去年拍照时只觉得这花很好看,没有其他感觉,今天就来看看绣球。什么是绣球花?绣球又名八仙花,为虎耳草科绣球属植物,一……科学家发现碳家族单晶新材料碳是我们这个星球上最重要的元素之一,碳原子具有极轻的原子质量和极强的共价键。碳是元素周期表中最多样化的元素之一,它可以与自身或者几乎所有的元素以多种杂化方式成键,获得结构丰富的……BlackBerryOS停止运行,一代神机黑莓输给了时代一代神机落幕,为黑莓手机打造的专属系统BlackBerryOS即将终止服务。近日,黑莓官方宣布,2022年1月4日后不再提供适用于BlackBerry7。1OS及更早版本……3000元就是14000泰铢,能在泰国旅游几天?3000元人民币能够兑换14000泰铢,这笔钱在泰国能享受哪些服务呢?(此处已添加小程序,请到今日头条客户端查看)外出游玩的国民,对东南亚地区都比较了解,尤其是泰国这个国……六百年紫禁城冬日故宫古建晚霞北京故宫无疑是拍摄古建的好去处,门票不是太贵,遗憾的是人太多。故宫古建为躲开众多的游人,冬季或许就成了进宫拍摄的最好季节了。其实冬季一是游人少,二是太阳的角度很低,……适量饮酒有益健康?柳叶刀错!一年74万人喝出癌症50岁的吴叔是一个嗜酒如命的人。一般的酒难入吴叔法眼,要喝,就一定要喝高浓度烈性白酒。几十年来,吴叔三餐不离酒,每天至少半斤白酒下肚。三个月前,吴叔突然感觉饮食困难,食物……穷则变,变则通当我们用上性价比高的小米油烟机时,雷军手机帝国已然完成了它的跨界,当我们享受着小米家电的高效服务时,诺基亚、统一、康师傅早已在中国纷纷倒下,跨界已然悄无声息地走进了我们的生活,……幻塔第一代执行者来了,曾是首席身份,能和斯嘉丽打平手?这几天玩《幻塔》,大家有没有眼馋过艾达之子的几个赦免天使?最早是拿着紫红色长刀的斯嘉丽,后来是半机甲装备出场的伊希斯,都给人一种很强的感觉。从早期官方发布的PV来看,完成……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网