容器中的Java堆大小调整:快速,轻松
在上一篇博客中,我们已经看到Java进行了改进,可以根据正在运行的环境(即物理机或容器(码头工人))识别内存。java的最初问题是,它无法弄清楚它是否在容器中运行,并且它曾经为容器运行所在的整个硬件捕获内存。(请参阅 -ttps://blogs.oracle.com/java/java-on-container-like-a-pro)
现在,在容器中运行的Java程序能够识别cgroup限制并根据该限制分配内存(堆)(如果我们未指定以前定义的最小和最大堆大小)。因此,我们可以在容器中运行Java程序并适当地利用硬件内存,但是我们可以确定Java程序是否根据cgroup定义使用了堆大小?
我们可以通过XshowSettings:category解决此问题 。 这是一个方便的HotSpot JVM标志(Java启动器java的选项)是-XshowSettings选项。Oracle Java启动器描述页面中对此选项进行了如下描述:
-XshowSettings:category
显示设置并继续。此选项的可能类别参数包括:
all
显示所有类别的设置。这是默认值。
locale
显示与语言环境相关的设置。
properties
显示与系统属性相关的设置。
vm
显示JVM的设置。
[Java技术说明中描述的这些类型的标志- 如 https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html ]
showSettings标志提供了有关该JVM中运行的程序的许多详细信息,但是,我们的兴趣是找出内存利用率,因此我们将坚持使用-> -XshowSettings:vm -version
让我们通过运行一个简单的容器程序而不指定cgroup标志(这会通知Java该程序正在Java容器中运行)来验证这一点。
(我将容器内存设置为100MB,而JVM将最大堆设置为3.24G)
[root java-8]# docker run -m 100MB oracle-server-jre java -XshowSettings:vm -version
VM settings:
Max. Heap Size (Estimated): 3.24G
Ergonomics Machine Class: server
Using VM: Java HotSpot(TM) 64-Bit Server VM
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)
我们可以清楚地看到Java Heap正在捕获硬件可用的堆,但是docker大小仅指定为100 mb。现在,让我们告诉Java程序正在容器内运行并查看结果。
仅使用jdk Docker的Java版本1.8.0_181(包括解锁实验版和具有内存1GB MB规范的Cgroup限制)
[root]# docker run -m 1GB oracle-server-jre java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XshowSettings:vm -version
VM settings:
Max. Heap Size (Estimated): 228.00M
Ergonomics Machine Class: server
Using VM: Java HotSpot(TM) 64-Bit Server VM
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)
JVM能够检测到只有1GB的容器,并将最大堆设置为228M,这几乎是可用总大小的1/4。
我们可以看到Java Heap设置为docker大小的1/4,而Docker则使用了3/4的其余内存,但是如果我们的容器不需要3/4内存,该怎么办,
如果容器或程序配置不需要那么多的内存,那么这不是对内存的正确利用。Java堆与容器大小之间的比率是在JVM代码中定义的,所以问题是-我们可以配置该比率吗?
是的,Java通过提供另一种选择来更改容器内存和Java堆大小的比率而做得很好。Java引入了另一个标志作为 MaxRAMFraction (该标志的默认值为4,因此堆大小占容器大小的1/4,我们可以通过显式定义它来更改它)
我们定义了RAM分数= 2,这使堆大小几乎占总数的50%。
[root]# docker run -m 1GB oracle-server-jre java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=2 -XshowSettings:vm -version
VM settings:
Max. Heap Size (Estimated): 455.50M
Ergonomics Machine Class: server
Using VM: Java HotSpot(TM) 64-Bit Server VM
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)
堆大小大约达到容器总大小的50%。
现在,我们也可以根据Java程序的舒适程度来更改该比率,但这又导致了另一种想法,即如果将该比率定义为1,则可以安全地运行容器?(但是JVM不会捕获全部容器内存,并且会留下一些内存来运行其他一些容器程序,例如容器调试外壳(docker exec)和诊断程序,OS进程等。如果程序或容器在负载下需要更多内存,则它将杀死容器,因此-XX:MaxRAMFraction=2 ,如果我们要自定义默认的JVM比率(这似乎是最安全的比率),我觉得定义最小比率似乎是安全的。
容器中的Java堆大小调整:快速,轻松的更多相关文章
- 优化Java堆大小的5个技巧
本文作者Pierre是一名有10多年经验的高级系统架构师,他的主要专业领域是Java EE.中间件和JVM技术.根据他多年的工作实践经验,他发现许多性能问题都是由Java堆容量不足和调优引起的.下面他 ...
- 优化Java堆大小5温馨提示
总结:Java没有足够的堆大小可能会导致性能非常大的影响,这无疑将给予必要的程序,并不能带来麻烦.本文总结了影响Java居前五位的能力不足,并整齐地叠优化? 笔者Pierre有一个10高级系统架构师有 ...
- 从容器里dump java堆实验探索(原创)
目标:从docker容器里dump java堆 模拟程序 占用空间500M, 设置启动JVM参数 docker启动命令 (PS:经过测试,至少要650M才能启动容器) 方式1: 通过docker ex ...
- Java堆大小[z]
JVM中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制:系统的可用虚拟内存限制:系统的可用物理内存限制. 32位系统下,一般限制在1.5G~2G:64为操作系统对内存 ...
- 如何规避容器内做Java堆dump导致容器崩溃的问题
写在前边 最近公司生产环境的容器云上出了个性能问题,为了做性能分析,使用 JDK 自带的 jmap 收集堆dump,出现了内存溢出导致了容器崩溃. 本篇文章将带你探究,如何规避容器内做堆 dump 导 ...
- 一步步优化JVM四:决定Java堆的大小以及内存占用
到目前为止,还没有做明确的优化工作.只是做了初始化选择工作,比如说:JVM部署模型.JVM运行环境.收集哪些垃圾回收器的信息以及需要遵守垃圾回收原则.这一步将介绍如何评估应用需要的内存大小以及Java ...
- matlab中增加Java VM 的堆空间(解决xml_io_tools出现的OutOfMemory问题)
今天用MATLAB写程序,调用了xml_io_tools(很赞的一个xml读写工具包)中的函数,但是由于我要书写的文件比较大,5m左右,运行时不知道xml_io_tools中的哪一块超出了java中的 ...
- (转)在Docker中运行Java:为了防止失败,你需要知道这些
转自:https://mp.weixin.qq.com/s?__biz=MzA5OTAyNzQ2OA==&mid=2649693848&idx=1&sn=4e9ef7e2a9d ...
- Java堆的理解
堆的核心概述 所有的对象实例以及数组都应当在运行时分配在堆上 从实际实用角度看 --"几乎所有的对象实例都在堆中分配内存" 数组和对象可能永远不会存储在栈上,因为栈帧中保存引用,这 ...
随机推荐
- PowerDesigner使用教程(二)
在PowerDesigner使用教程(一)中已经介绍了基本用法,下面介绍一些使用技巧. 1. 生成sql脚本 Database→Generate Database 选择要输出的文件路径,即文件存储路 ...
- [Python基础]006.IO操作
IO操作 输入输出 print raw_input input 文件 打开文件 关闭文件 读文件 写文件 文件指针 实例 输入输出 输入输出方法都是Python的内建函数,并且不需要导入任何的包就可以 ...
- 小工具之apk黑屏自动检测
在打包测试的时候经常发送给测试组之后,发现已进入游戏就黑屏,这个就浪费了测试组的精力,如果要测试多款产品的话,就会因为黑屏问题做很多无用功,这是程序就需要在发给测试的时候自己先测试产品会不会黑屏.同样 ...
- CopyOnWriteArrayList(写入并复制) & CountDownLatch(闭锁)
ConcurrentHashMap: ①Java 5.0 在 java.util.concurrent 包中提供了多种并发容器类来改进同步容器 的性能.② ConcurrentHashMap 同步容器 ...
- ecilpse 纠错插件
在market里面搜索 Spot Bugs Unnecessary Code Detector
- JAVASE(十六) IO流 :File类、节点流、缓冲流、转换流、编码集、对象流
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 1.File类型 1.1.File类的理解 File类是在java.io包下 File可以理解成一个文件 ...
- Spring Cloud 系列之 Apollo 配置中心(三)
本篇文章为系列文章,未读前几集的同学请猛戳这里: Spring Cloud 系列之 Apollo 配置中心(一) Spring Cloud 系列之 Apollo 配置中心(二) 本篇文章讲解 Apol ...
- Java实现 LeetCode 788 旋转数字(暴力)
788. 旋转数字 我们称一个数 X 为好数, 如果它的每位数字逐个地被旋转 180 度后,我们仍可以得到一个有效的,且和 X 不同的数.要求每位数字都要被旋转. 如果一个数的每位数字被旋转以后仍然还 ...
- Java实现 LeetCode 87 扰乱字符串
87. 扰乱字符串 给定一个字符串 s1,我们可以把它递归地分割成两个非空子字符串,从而将其表示为二叉树. 下图是字符串 s1 = "great" 的一种可能的表示形式. grea ...
- Java中构造方法的详细介绍
构造方法是一个特殊的方法 它会在实例化对象时自动调用 构造方法的定义 必须同时满足下面的三个条件 方法名与类名相同 方法名前面没有返回值类型的声明 在方法中不能使用return语句返回值 class ...