过度配置堆上的OutOfMemoryError

在分配一个应该很适合我为JVM提供的堆中的数据结构时,为什么会出现OutOfMemoryError? 这是我最近遇到的一个问题。

确实,当查看开发人员要完成的工作并通过-Xmx参数对提供给JVM的堆大小进行三重检查时,似乎确实存在着一些可疑之处。

30分钟后,我们了解了情况并解开了谜团。 但这确实起初并不明显,所以我认为如果我更详细地描述根本问题,可能会节省一天的时间。

与往常一样,了解问题的最佳方法是通过动手实例。 我构建了一个小的综合测试用例:

package eu.plumbr.demo;
class ArraySize {public static void main(String... args) {int[] array = new int[1024*1024*1024];}
}

代码很简单–它要做的就是分配一个包含十亿个元素的数组。 现在,考虑到java int原语需要4个字节,因此人们可能会认为使用6g堆运行代码可以很好地运行。 毕竟,这十亿个整数应该只消耗4g内存。 那么为什么执行代码时会看到以下内容?

My Precious:bin me$ java –Xms6g –Xmx6g eu.plumbr.demo.ArraySize
Exception in thread "main" java.lang.OutOfMemoryError: Java heap spaceat eu.plumbr.demo.ArraySize.main(ArraySize.java:6)

在投入更多的堆之前(事实上,使用–Xmx7g ,上面的示例运行得很好),让我们尝试了解为什么我们的期望是错误的。

首先– Java中的int原语确实需要4个字节。 因此,这并不意味着我们的JVM实现一夜之间变得疯狂。 而且我可以向您保证,数学运算也是正确的– 1024 * 1024 * 1024 int原语确实需要4,294,967,296字节或4 GB。

要了解发生了什么,让我们运行相同的情况,并通过指定–XX:+ PrintGCDetails来打开垃圾收集日志记录

My Precious:bin me$ java –Xms6g -Xmx6g -XX:+PrintGCDetails eu.plumbr.demo.ArraySize-- cut for brevity --Exception in thread "main" java.lang.OutOfMemoryError: Java heap spaceat eu.plumbr.demo.ArraySize.main(ArraySize.java:6)HeapPSYoungGen      total 1835008K, used 125829K [0x0000000780000000, 0x0000000800000000, 0x0000000800000000)eden space 1572864K, 8% used [0x0000000780000000,0x0000000787ae15a8,0x00000007e0000000)from space 262144K, 0% used [0x00000007e0000000,0x00000007e0000000,0x00000007f0000000)to   space 262144K, 0% used [0x00000007f0000000,0x00000007f0000000,0x0000000800000000)ParOldGen       total 4194304K, used 229K [0x0000000680000000, 0x0000000780000000, 0x0000000780000000)object space 4194304K, 0% used [0x0000000680000000,0x0000000680039608,0x0000000780000000)PSPermGen       total 21504K, used 2589K [0x000000067ae00000, 0x000000067c300000, 0x0000000680000000)object space 21504K, 12% used [0x000000067ae00000,0x000000067b087668,0x000000067c300000)

答案现在正盯着我们的眼睛:即使我们有很多可用的总堆,堆中的单个区域也没有足够大的空间来容纳4g对象。 我们的6g堆分为四个单独的区域,大小如下:

  • 伊甸园15.36亿
  • 生存空间( )每个256M
  • 老一代4,096M

现在,牢记对象分配必须适合单个区域,我们确实可以看到应用程序没有机会-我们的任何堆区域中都没有足够的空间来容纳此4g分配。

那么–我们现在唯一的希望是进一步增加堆数吗? 即使我们已经提供了将近50%的超额配置-将6g堆交给应该适合4g的数据结构? 没那么快–有替代解决方案可用。 您可以设置内存中不同区域的大小。 它并不像人们期望的那样简单易用,但对启动配置进行两次小的修改就可以解决问题。 使用两个额外的选项启动相同的代码时:

My Precious:bin me$ java -Xms6g -Xmx6g -XX:NewSize=5g -XX:SurvivorRatio=10 eu.plumbr.demo.ArraySize

然后程序执行其工作,并且不会引发OutOfMemoryError。 在启动中添加-XX:+ PrintGCDetails也会对此进行说明:

HeapPSYoungGen      total 4806144K, used 4369080K [0x00000006c0000000, 0x0000000800000000, 0x0000000800000000)eden space 4369408K, 99% used [0x00000006c0000000,0x00000007caaae228,0x00000007cab00000)from space 436736K, 0% used [0x00000007e5580000,0x00000007e5580000,0x0000000800000000)to   space 436736K, 0% used [0x00000007cab00000,0x00000007cab00000,0x00000007e5580000)ParOldGen       total 1048576K, used 0K [0x0000000680000000, 0x00000006c0000000, 0x00000006c0000000)object space 1048576K, 0% used [0x0000000680000000,0x0000000680000000,0x00000006c0000000)PSPermGen       total 21504K, used 2563K [0x000000067ae00000, 0x000000067c300000, 0x0000000680000000)object space 21504K, 11% used [0x000000067ae00000,0x000000067b080c90,0x000000067c300000)

我们看到,现在的区域大小确实是我们所要求的:

  • 如我们的-XX:NewSize = 5g参数所指定,年轻大小int总数(eden +两个幸存者空间)为5g
  • 如我们用-XX:SurvivorRatio = 10参数指定的,Eden比幸存者大10倍。

请注意,在我们的情况下,两个参数都是必需的。 仅指定-XX:NewSize = 5g仍会以某种方式将其在伊甸园和幸存者之间分割,使得任何区域都无法容纳所需的4g。

希望阅读此说明将为您节省以后的调试时间。 或帮助您避免过度配置资源。

翻译自: https://www.javacodegeeks.com/2014/05/outofmemoryerror-on-overprovisioned-heap.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/341159.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

E: Couldn‘t find any package by regex ‘python3.6‘的解决方式

一 问题描述 安装python较高版本。按照网上提供的参考资料,运行相关命令 sudo apt-get install python-software-properties sudo apt-get install software-properties-common sudo add-apt-repository ppa:jonathonf/python-3.6 sudo apt-get update sudo apt…

如何在Java中修复表达式的非法开头

您是否遇到过这个令人难以置信的错误,想知道如何解决它? 让我们浏览一下这篇文章,研究如何解决表达式Java非法开头错误。 这是一个动态错误,这意味着编译器会发现某些不符合Java编程规则或语法的内容。 初学者大多会遇到Java中的…

apt-cache 命令

一 命令介绍 apt-cache 命令可显示 APT 内部数据库里的多种信息。这些信息是从 sources.list 文件内聚集不同来源的缓存。于运行 apt update 运作时产生的。 APT包管理器工作在软件包元数据的本地缓存上。通过apt-cache命令,可以查询本地APT缓存并获得相关信息。 …

apt-get install 和pip install 、 apt与apt-get之间的区别 的区别

1 apt-get install 和pip install 的区别 区别: pip install 主要安装pypi上已经上传的包或库,主要和编程语言python 有关的包,可以选择版本,或者在已有的新版本上安装旧版本sudo apt-get install 是用于系统升级下载相关的软件…

Ubuntu下环境变量

一 环境变量是什么 环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数。如:临时文件夹位置和系统文件夹位置等。简单理解:就是系统运行时所需要的一些参数。

高效的企业测试-结论(6/6)

该系列的最后一部分将涵盖其他端到端测试,生产中的测试以及各部分的结论。 进一步的端到端测试和生产中的测试 除了仅验证单个被测应用程序并模拟外部问题的系统测试之外,我们的管道还必须包括完整的端对端测试,以验证整个系统。 好消息是&…

在Word中如何调整编号和文字之间的间距?

https://jingyan.baidu.com/article/48b558e32a80b53e39c09a77.html 首先,打开或者新建一份需要编辑的Word文档。如图: 2 接着,选中需要调整编号与文字之间间距的文字。如图: 3 接着,右键单击鼠标,在弹…

word编号和文本间距过大

问题: word中编号和文本间距过大 解决办法: 在正文中,调整列表缩进——更多——编号之后——设置为“空格”。 如果经过1步骤后,正文中的编号和后面的问题间距过大,可以执行, 段落——缩进——左侧——设置为0——缩进…

将Spock 1.3测试迁移到Spock 2.0

了解Spock 2.0 M1(基于JUnit 5)的期望,如何在Gradle和Maven中迁移到它以及为什么报告发现的问题很重要:)。 重要说明 。 我绝对不建议您永久将您的现实项目迁移到Spock 2.0 M1! 这是2.x的第一个&#xff0…

Word使用中常用的快捷键

1. 字体放大缩小 Ctrl ] 放大字体 Ctrl [ 缩小字体 选中文本,按快捷键即可看到效果。 2 对齐文本 左对齐:Ctrl L 右对齐:Ctrl R 居中对齐:Ctrl E 3 符号上下标 下标:【Ctrl】【】 上标:【C…

创建快捷方式时如何不带“快捷方式“后缀字样?

方法一: 去除“快捷方式”字样的方法: 创建快捷方式,使用上述方法比较繁琐,我们往往直接右击要创建快捷方式的文件或文件夹,然后“发送到”→“桌面快捷方式”。这样创建的,还会带“快捷方式”字样&#xf…

java akka_用于大型事件处理的Akka Java

java akka我们正在设计一个大型的分布式事件驱动系统,用于跨事务数据库的实时数据复制。 来自源系统的数据(消息)在到达目的地之前经历了一系列转换和路由逻辑。 这些转换是多进程和多线程的操作,包括可以同时执行的较小的无状态步…

xftp的简单使用

xftp的简单使用 1.下载并安装Xftp工具。打开Xftp工具,点击“新建”。 2.在“新建会话属性”中选择“名称”为主机命名,在“主机”栏输入主机IP,“协议”和“端口号”使用sftp和22,在“用户名”和“密码“栏输入账户密码。点…

与OutOfMemoryError相关的JVM参数

JVM提供了有用的参数来处理OutOfMemoryError 。 在本文中,我们要强调那些JVM参数。 在对OutOfMemoryError进行故障排除时,它可能对您很方便。 这些JVM参数是: -XX: HeapDumpOnOutOfMemoryError -XX:HeapDumpPath -XX…

This beta version of Typora is expired, please download and install a newer;解决方法

亲测可行的方法,方便永久 1.打开注册表 cmd(Win R)–>regedit 2.修改Typora权限 计算机\HKEY_CURRENT_USER\Software\Typora 右键Typora选择权限打开,然后选择拒绝 注意需要选择好组与用户名【最直接的就是所有用户与组均点…

IEEE在指定期刊下搜索相关论文

在左边Publication Title中直接输入目标期刊,搜索后结果显示指定期刊下文章

操作方法:Spring Boot和Thymeleaf与Maven

Spring Boot是一款出色的软件,可让您在几秒钟内引导Spring应用程序。 它确实有效。 尽可能少的配置即可上手。 而且仍然可以更改默认值。 让我们看看用Thymeleaf和Maven引导Spring MVC并在IntelliJ中使用它是多么容易。 Spring MVC Thymeleaf与Maven的基本设置 确…

Ubuntu安装VSCode

1. 一般方法: 首先是进入到vscode官网:https://code.visualstudio.com/Download ,选择.deb包下载 但是下载deb包时,速度很慢而且一直提示“网络连接已断开” 2. 解决办法: 将下载地址中 az764295.vo.msecnd.net 替换…

如何在Java中使用正则表达式?

正则表达式是用于文本搜索的非常重要的工具。 以下是用于执行正则表达式搜索并基于正则表达式捕获字符串的不同部分的代码段 public class RegexTest { public static void main(String[] args) { String name "01_My-File.pdf" ; match(name); match( "09_03_…

xxx is not in the sudoers file.This incident will be reported错误

一 问题解决 在执行sudo命令时会有如下提示: xx is not in the sudoers file. This incident will be reported. 原因分析:一般这种情况是创建了新用户,没有对应修改sudoers文件或者group文件。 解决方法: 方法1:…