实战项目中Java heap space错误的解决
部标GPS通讯系统在上线之后,经过不断调试,终于稳定运行一段时间,后来又遇到了Java heap space错误异常!日志如下:
说明系统中有未释放的对象。如何找出这些未释放对象以及监控JVM堆内存,优化代码释放内存对象呢?还有JVM的垃圾回收机制是如何运作的呢?
首先在系统启动运行的时候打开记录GC详细信息,运行脚本如下:
看看GC详细日志,当GC到13400多次的时候新生代和老生代的堆内存几乎用满了,频繁触发Full GC (Ergonomics) ,直到没有内存空间给新生对象了。所以JVM抛出了内存溢出错误!进而导致程序崩溃。
首先简单了解下JVM垃圾回收机制:
从上图可以看出 GC 的主要收集区域,包括 PSYoungGen(年轻代)、ParOldGen(老年代)、Metaspace(元数据区)。
新生代:新创建的对象都是用新生代分配内存,Eden空间不足时,触发Minor GC,这时会把存活的对象转移进幸存者Survivor区。
老年代:老年代用于存放经过多次Minor GC之后依然存活的对象。
新生代的GC(Minor GC):新生代通常存活时间较短基于Copying算法进行回收,所谓Copying算法就是扫描出存活的对象,并复制到一块新的完全未使用的空间中,对应于新生代,就是在Eden和FromSpace或ToSpace之间copy。
新生代采用空闲指针的方式来控制GC触发,指针保持最后一个分配的对象在新生代区间的位置,当有新的对象要分配内存时,用于检查空间是否足够,不够就触发GC。当连续分配对象时,对象会逐渐从Eden到Survivor,最后到老年代。
老年代的GC(Major GC/Full GC):老年代与新生代不同,老年代对象存活的时间比较长、比较稳定,因此采用标记(Mark)算法来进行回收,所谓标记就是扫描出存活的对象,然后再进行回收未被标记的对象,
回收后对用空出的空间要么进行合并、要么标记出来便于下次进行分配,总之目的就是要减少内存碎片带来的效率损耗。
附上堆结构图:
至此,在已经尝试了将Java虚拟机中Xms(初始堆大小-2G)和Xmx(最大堆大小-4G)参数调大之后也无果,只能从代码入手, 对象一直堆积于老年代未被释放,应该是代码中对象未被释放。
为了找出代码中未被释放的对象,这里运用到了内存监控工具jconsole和内存堆对象统计工具jmap。
jconsole.exe位于bin目录下,用法也挺简单的,用于调优后的监控还不错,这里留个图不做介绍了
这里运用jmap(jdk自带的jvm内存分析的工具),将程序堆对象统计出来的结果如下:
发现到代码问题:应该是解析协议的时候CanDataItem对象不断被new出来,使用完了以后并未被GC回收留在老生代,
找到CanDataItem使用完成的地方做了如下修改:
修改代码再将T808Message等类用完了的地方做了释放,之后终于解决了问题!修改代码以后再次使用jmap统计如下,正常了!
附 - jmap输出中class name非自定义类的说明:
BaseType Character | Type | Interpretation |
---|---|---|
B | byte | signed byte |
C | char | Unicode character |
D | double | double-precision floating-point value |
F | float | single-precision floating-point value |
I | int | integer |
J | long | long integer |
L; | reference | an instance of class |
S | short | signed short |
Z | boolean | true or false |
[ | reference | one array dimension,[I表示int[] |
总结导致java.lang.OutOfMemoryError异常的常见原因有以下几种:
- 内存中加载的数据量过于庞大,如一次从数据库取出过多数据;
- 集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;
- 代码中存在死循环或循环产生过多重复的对象实体-----(本例中);
- 使用的第三方软件中的BUG;
- 启动参数内存值设定的过小;
至此问题总算解决了,通常情况下,Java开发人员并不需要去关心JVM是如何运行的。即使不理解JVM的工作原理,也不会给开发人员带来过多困惑。Java程序员更容易忽视基础技术。
“蚓无爪牙之利,筋骨之强,上食埃土,下饮黄泉,用心一也。蟹六跪而二螯,非蛇蟮之穴无可寄托者,用心躁也”。对于技术人员来说,如果长期忽略自身技术的根基而去一昧地追求高层框架技术,这无疑是舍本求末的做法。
JVM的出现,为程序员屏蔽了操作系统与硬件的细节,使得程序员从诸如内存管理这样的繁琐任务中解放出来。但这不并等同于允许Java程序员放弃对基础的重视。
事实上,任何平台的程序员都应当了解平台的基本特性、实现机制以及接口,这是提高自身修养的必经之路。对于Java程序员来说,我们还是需要多多了解JVM。
了解JVM的基本实现机制,不仅对于解决实际应用中诸如GC等虚拟机问题时有直接帮助,还有利于我们更好地理解语言本身。
转载请注明出处!谢谢!https://www.cnblogs.com/lys_013/p/9605352.html
实战项目中Java heap space错误的解决的更多相关文章
- Eclipse 报 “Exception in thread "main" java.lang.OutOfMemoryError: Java heap space ”错误的解决办法
1.打开Eclipse软件,选择菜单栏run,在二级菜单中选择 Debug Configurations... 项,如下图所示. 2.在弹出的窗口中选择 (x)=Arguments 选项卡,VM a ...
- java.lang.OutOfMemoryError: Java heap space错误及处理办法(收集整理、转)
下面是从网上找到的关于堆空间溢出的错误解决的方法: java.lang.OutOfMemoryError: Java heap space ============================== ...
- java.lang.OutOfMemoryError: Java heap space错误及处理办法
以下是从网上找到的关于堆空间溢出的错误解决办法: java.lang.OutOfMemoryError: Java heap space ============================= ...
- java.lang.OutOfMemoryError: Java heap space错误和方法(集、转)
错误的方式来解决溢出下面的堆空间是从网上找: java.lang.OutOfMemoryError: Java heap space ================================= ...
- 转:java.lang.OutOfMemoryError: Java heap space错误及处理办法(收集整理、转)
以下是从网上找到的关于堆空间溢出的错误解决办法: Java.lang.OutOfMemoryError: Java heap space =============================== ...
- 创建Maven项目出现:An internal error occurred during: "Retrieving archetypes:". Java heap space 错误解决办法
首先说明一下网上的方法: 在Eclipse中创建Maven的Web项目时出现错误:An internal error occurred during: "Retrieving archety ...
- Tomcat报java.lang.OutOfMemoryError: Java heap space错误停止运行如何解决
最近开发的一个商业项目,部署完成后,经常出现Tomcat挂掉的现象,报的异常是:java.lang.OutOfMemoryError: Java heap space,上网google了一下,了解了一 ...
- 内存大小设置 Java heap space错误
1. 问题描述 当从数据库中查询大量的数据,每个模板取出来几百万条数据,或者是频繁的刷新项目.模板时就会占用Java虚拟机JVM的大量内存,超过内存就会出现报java.lang.OutOfMemory ...
- IBM Worklight OutOfMemoryError: Java heap space 错误
在启动 IBM Worklight 6.0 server 的时候,报了一个 OutOfMemory 的错误: [INFO ] FWLSE4006I: Worklight Studio is ...
随机推荐
- [Swift]LeetCode869. 重新排序得到 2 的幂 | Reordered Power of 2
Starting with a positive integer N, we reorder the digits in any order (including the original order ...
- [Swift]LeetCode995. K 连续位的最小翻转次数 | Minimum Number of K Consecutive Bit Flips
In an array A containing only 0s and 1s, a K-bit flip consists of choosing a (contiguous) subarray o ...
- kernel:NMI watchdog: BUG: soft lockup - CPU#6 stuck for 28s! CentOS7linux中内核被锁死
环境说明:虚拟机 CentOS7中解压一个8G的包时,内核报错 Message from syslogd@cosmo-01 at Apr 25 11:05:59 ... kernel:NMI watc ...
- 定时任务 winform开发
在项目中我们经常遇到与时间结合的无限或者有限轮回的任务.例如每月一号统计工作量,基本这种情况,都会是设置定时任务,定时执行.好了,下面就记录一下定时任务的开发吧. 首先描述一下开发思路: 建立一个wi ...
- python高级-动态特性(20)
一.动态语⾔的定义 动态语言是在运行时确定数据类型的语言.变量使用之前不需要类型声明,通常变量的类型是被赋值的那个值的类型.现在比较热门的动态语言有:Python.PHP.JavaScript.Obj ...
- C# 调用IP库(QQWry.Dat)查询IP位置及自动升级IP库方法【转】
前言 C# 用IP地址(123.125.114.144)查询位置(北京市百度公司)的东西,非常好用也非常方便,可手动升级刷新IP库,一次编码永久收益,可支持winform.asp.net等程序. 本文 ...
- cmake安装配置及入门指南
前言 今天,从github下载代码学习,让我用cmake编译,纳尼?make我知道,cmake是啥鬼?天啊,无知很可怕!赶紧mark一波,虽然很耽误学习进度,但感觉还是要get一波! 一.安装准备 感 ...
- dbcontext实例创建问题
dbcontext初始化 Private DemoContext db=new DemoContext (): 问题:什么时候释放db对象? 使用Using()方法中创建,每次调用会造成频繁的连接关闭 ...
- 2.计算机组成-数字逻辑电路 门电路与半加器 异或运算半加器 全加器组成 全加器结构 反馈电路 振荡器 存储 D T 触发器 循环移位 计数器 寄存器 传输门电路 译码器 晶体管 sram rom 微处理 计算机
现代计算机的各个部件到底是如何通过逻辑电路构成的呢 半加器 我们说过了门电路 看似简单的三种门电路却是组成了整个逻辑电路的根基 真值表--其实就是根据输入输出状态枚举罗列出来的所有可能 比如有一台 ...
- SpringBoot整合系列-整合Swagger2
原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9959844.html SpringBoot整合Swagger2 步骤 第一步:添加必要的 ...