调整JVM堆内存解决OutOfMemoryError
今天在用 processing(http://zh.wikipedia.org/wiki/Processing) 编写处理 midi 文件的程序的时候,遇到了一个问题。程序主要是读取分析 midi ,然后用波形模拟 midi 中的信息,最后记录相应内容,创建 wav 文件。在使用 WaveFileWriter 写文件的时候,因为波形数据较多,使用 new byte[139708800] 创建了一个大小约为134M的 byte 数组,导致程序抛出 java.lang.OutOfMemoryError: Java heap space。
起初我想到可能原因是 JVM 的 HeapSize 大小不够,在 cmd 中查看,发现初始大小是下图这样的。也就是初始堆大小为 16777216 bits,也就是16M;堆的最大值是268435456 bits,也就是256M。而我需要创建的byte数组是134M,很可能heap space会不够。于是我就在系统变量里添加了"_JAVA_OPTIONS",将值设为"-Xmx1024m"。
起初我以为经过这样的设置,应该就没有问题了。但是事实情况是,我重新运行了几次程序,有时候不会OOME,有时候会OOME。于是我就用jconsole去监控JVM内存使用情况,发现不管是否抛出OOME,堆内存都分配了134M的空间给我的byte数组。(jconsole是安装jdk时候自带的,如果配置了java环境变量,可以直接在cmd中输入"jconsole"即可启动)
于是我猜想,是不是因为没有将 -Xms 和 -Xmx 设置为一样,从而导致垃圾回收之后,虚拟机重新分配内存不及时,导致错误率先抛出?按照 Java SE hotspot 的说明文档,如果 InitialHeapSize 和 MaxHeapSize 不一样,那么在运行过程中 JVM 会自动调整内存大小,默认值是上升20%。(具体值可在cmd中查看)这样的话,为了分配134M的内存,需要经过多次增长,所以有时内存重新分配快,就没有OOME,有时候重新分配慢,就会有OOME。不管怎样,为了避开这个问题,我就将"_JAVA_OPTIONS"系统变量的值设定为"-Xms1024m -Xmx1024m"。不过这次出现了新的问题,也是OOME,但是不是java heap space,而是outputstream.write(byte[]) (native method) 出现了OOME。原因是我将JVM的内存设置太大,导致Direct Memory不够了,执行本地方法的时候内存不足。于是我重新调整JVM的内存大小为512M,最终解决了问题。
解决问题的关键点在三处:
- OutOfMemoryError: java heap space ,可以通过上调Xmx解决。
- OutOfMemoryError 如果是由于本地方法产生的,应该下调Xmx。这种解决问题的技巧在周志明的《深入理解java虚拟机》中有讲到。
- 学会用jconsole去监控内存使用情况。
这次最终还残留了一个问题没有解决,为什么只设置-Xmx参数之后,OOME会间歇性出现。我只是猜想原因,真正的原因还有待验证。并且我还没有想到好的验证方法,希望有经验的朋友能帮忙指出!
调整JVM堆内存解决OutOfMemoryError的更多相关文章
- 【转】JVM 堆内存设置原理
堆内存设置 原理 JVM堆内存分为2块:Permanent Space 和 Heap Space. Permanent 即 持久代(Permanent Generation),主要存放的是Java类定 ...
- [转]JVM 堆内存设置原理
堆内存设置 原理 JVM堆内存分为2块:Permanent Space 和 Heap Space. Permanent 即 持久代(Permanent Generation),主要存放的是Java类定 ...
- JVM 堆内存设置原理
堆内存设置 原理 JVM堆内存分为2块:Permanent Space 和 Heap Space. Permanent 即 持久代(Permanent Generation),主要存放的是Java类定 ...
- JVM 堆内存设置原理(转)
堆内存设置 原理 JVM堆内存分为2块:Permanent Space 和 Heap Space. Permanent 即 持久代(Permanent Generation),主要存放的是Java类定 ...
- 巩固java(二)----JVM堆内存结构及垃圾回收机制
前言: 我们在运行程序时,有时会碰到内存溢出(OutOfMemoryError)的问题,为了解决这种问题,我们有必要了解JVM的内存结构和垃圾回收机制. 正文: 1.JVM堆内存结构 ...
- JDK8中JVM堆内存划分
一:JVM中内存 JVM中内存通常划分为两个部分,分别为堆内存与栈内存,栈内存主要用运行线程方法 存放本地暂时变量与线程中方法运行时候须要的引用对象地址. JVM全部的对象信息都 存放在堆内存中.相比 ...
- jvm堆内存和GC简介
最近经常遇到jvm内存问题,觉得还是有必要整理下jvm内存的相关逻辑,这里只描述jvm堆内存,对外内存暂不阐述. jvm内存简图 jvm内存分为堆内存和非堆内存,堆内存分为年轻代.老年代,非堆内存里只 ...
- JVM堆内存监测的一种方式,性能调优依旧任重道远
上月,由极客邦.InfoQ和听云联合主办2016 APMCon中国应用性能管理大会圆满落下帷幕.会上,Java冠军Martijn Verburg进行了一场Java and the Machine的分享 ...
- JVM堆内存设置
今天碰到了一个题目,讲的是关于堆内存的问题,题目如下 下面哪种情况会导致持久区jvm堆内存溢出? A.循环上万次的字符串处理 B.在一段代码内申请上百M甚至上G的内存 C.使用CGLib技术直接操 ...
随机推荐
- 《从零开始学Swift》学习笔记(Day 18)——有几个分支语句?
原创文章,欢迎转载.转载请注明:关东升的博客 分支语句又称条件语句,Swift编程语言提供了if.switch和guard三种分支语句. if语句 由if语句引导的选择结构有if结构.if ...
- python3使用SMTP发送邮件
环境:python3 ,IDE : pycharm 非常奇怪的是,用163发送邮件,如果电脑连校园网发送,会被当成垃圾邮件拒绝 如果用手机开热点就可以正常发送 代码如下 #!/usr/bin/pyth ...
- 关于JAVA中String类型的最大长度
前些天看到一道面试题,题目很容易理解:String的长度限制是多少? 针对这个题目,浏览了网友的回答,大概得到了3个层次的答案. 最浅的层次: 近似计算机内存大小的长度.这是作为一个程序员最浅显的回答 ...
- js的简单的逻辑算法题
比如题目:寻找1~1000之内,所有能被5整除.或者能被6整除的数字 1 for(var i = 1 ; i <= 1000 ; i++){ 2 if(i % 5 == 0 || i % 6 ...
- ng-disabled的使用
1.适用范围 该指令适用于<input>, <select>,<button> 和 <textarea> 元素. 2.用法解析 ng-disabled ...
- 部署samba
1.首先需要关闭防火墙 2,创建用户名 3.IP地址配置ping下能不能成功 4.yum install samba -y 进行软件包的安装 5,vim修改.etc/samba/smb.conf/的配 ...
- 算法训练 s01串
问题描述 s01串初始为"0" 按以下方式变换 0变1,1变01 输入格式 1个整数(0~19) 输出格式 n次变换后s01串 样例输入 3 样例输出 101 数据规模和约定 0~ ...
- python3 中引用 HTMLTestRunner.py 模块的注意事项
HTMLTestRunner.py支持python2中运行,如果在python3.6.2中引用HTMLTestRunner.py模块,需要做一下更改: 1.更改HTMLTestRunner.py模块中 ...
- 通过存储过程运行通过DBLINK的查询语句失败-单个语句成功--ORA-00604
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/q947817003/article/details/24419459 客户遇到个问题,描写叙述例如以 ...
- MySQL学习思维导图
结束:分享在线下载地址 https://www.xmind.net/m/7t6U/