`
richard_lee
  • 浏览: 16377 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

由一个CUP占用率过高的问题去理解Java垃圾回收机制

阅读更多
最近我们的高并发平台遇到用户高峰运行时总会出现CPU占用率过高的问题,经过一段时间的排查及查阅相关的JVM资料,发现在程序中有这样一块代码引起了注意:



首先我们需要了解一下JVM的垃圾收集算法:
1、标记-清除算法
最基础的收集算法是“标记-清除”算法,顾名思义,算法分为“标记”和“清除”两个阶段:首先标记出所有要回收的对象,在标记完成之后统一回收所有被标记的对象。
缺点:一是时间问题,标记和清除两个过程效率都不高。二是空间问题,标记清除之后会产生大量不连续的内存碎片。
2、复制算法
该算法的思想是将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这块的内存用完了,则将还存活的对象复制到另外一块内存上去,然后再把刚使用过的内存空间一次清理掉。从而达到了每次垃圾回收时只是针对其中一块,避免了产生内存碎片等情况。
缺点:该算法的代价是只是使用了其中一半的内存,代价未免太高。
IBM研究曾表明,98%的新生代对象都是存活周期很短。比如在HotSpot虚拟机中,新生代中Eden和Survivor的大小比例为8::1,因为新生代的对象需要回收的概率大(对象的生命周期短,存活率低),所以内存的可用率达到了90%(新生代分为:Eden和两块Survivor)。
3、标记-整理算法
标记过程仍然和“标记-清除”算法一样,但后续步骤不是直接对可回收的对象进行清理,而是让所有存活的对象移动到移动,然后直接清理掉端边界以外的内存。
4、分代收集算法
当代商业虚拟机都使用“分代收集”算法,它是根据对象存活周期不同将内存划分几块。一般是把java堆分为新生代和老年代。在新生代中,每次垃圾回收都有大量对象死亡,只有少量才存活,就可采用复制算法。而老年代中,对象存活率高,就必须使用“标记-清除”或者“标记-整理”算法。
大概了解JVM的垃圾收集算法之后,还需要知道一个Java大对象的概念。
大对象是指需要大量连续内存空间的Java对象,最典型的就是大对象就是那些很长的字符串和数组,例如byte[]数组就是典型的大对象。说到这里,我觉得大部分同学应该就能发现上面的程序中存在严重大对象的问题,没错,在高并发的情况下这块程序会产生一大波短命大对象,这对java垃圾收集简直是噩梦,这回不停的触发垃圾收集在新年代进行内存复制,从而导致严重消耗CUP资源。
问题找到了,那我们接着就要找对应的解决方案
1、针对请求的信息,我们发现不需要那么大的分配空间,byte[100]就可以满足要求。
2、JVM提供一个-XX:PretenureSizeThreshold参数,另大于这个对象的参数直接在老年代进行分配,避免在Eden和连个Survivor之间进行大量的内存复制。
经过优化设置之后,系统的CUP占用率过高问题得到了明显的改善。
通过这次实际遇到的问题,让我对Java垃圾回收机制有了更深的理解,以后底层程序优化处理,jVM垃圾回收是一个必须考虑的问题。
  • 大小: 36.6 KB
分享到:
评论

相关推荐

    java cpu 内存占用高 问题 模拟并排查

    java cpu 内存占用高 问题 模拟并排查 https://blog.csdn.net/jiankunking/article/details/79749836 https://blog.csdn.net/jiankunking/article/details/79749483

    Android 查看CUP占用率

    ### Android查看CPU占用率 在Android开发过程中,了解应用程序对CPU资源的...同时,文章还通过一个具体的案例演示了如何解决因CPU过度占用而引起的问题。希望本文能够为从事Android开发工作的朋友们提供有价值的参考。

    java_cup_v10k.rar_java c++_java cup_java-c_java_cup.z_java_cup_v

    Java_CUP_v10k是一个基于Java的词法和语法分析工具,主要用于自动生成Java代码。这个工具的主要功能是解析用户定义的文法规范(通常为`.cup`文件),然后生成对应的解析器和词法分析器(lexer)的Java源代码。在软件...

    CUP 的使用方法 java 大全

    CUP(Java-Based Constructor of Useful Parsers)是一个用于生成LALR解析器的系统,它在功能上类似于经典的YACC程序。CUP以其简洁的规格说明为基础,允许用户嵌入Java代码,生成的解析器是用Java实现的,这与YACC...

    C# 获取当前所有进程线程CUP占用率

    监控系统所有进程的CPU使用...在CSDN上找到两个都不太好用,自己写了一个VS2013环境下编译通过 也可以直接运行\bin\Debug目录下的ConsoleApplication1.exe文件 用途:查看自己写的程序那个线程运行时间最多,耗资源等。

    java_cup_v10k.zip(里面含有英文文档)

    - **CHANGELOG**:记录了CUP从一个版本到另一个版本的更新和变更,包括错误修复、新功能添加等,对于了解CUP的历史发展和当前版本的改进非常有帮助。 - **cup_logo.gif**:CUP的标识图形,通常用于文档或网站以...

    gilde 自定义gif解码器 解决太多gif导致cup占用率高

    然而,标准的GIF解码器在处理大量动态图片时,可能会导致CPU占用率过高,从而影响应用的性能和用户体验。为了解决这个问题,开发者可以采用自定义的GIF解码器,比如基于`FrameSequenceDrawable`在Android 7.0及更高...

    教你找出 运行java项目,使cpu 100%,如何排查出是哪个jar包的哪个线程导致的

    在Java开发过程中,有时会遇到项目运行时CPU占用率达到100%的问题,这可能是由于某个线程...通过深入理解这些工具和方法,你可以有效地预防和解决Java项目运行时CPU使用率过高的问题,从而确保应用程序的稳定性和效率。

    java_cup.jar

    java_cup.jar

    CPU实用率过高解决办法

    CPU实用率过高通常是计算机性能问题的主要表现之一,它意味着处理器在大部分时间里都在全力工作,没有足够的空闲时间处理其他任务。这种情况可能会导致系统运行缓慢、响应延迟甚至系统崩溃。以下是一些解决CPU高占用...

    asp.net监测CPU占用率-点线图展示

    在ASP.NET环境中,开发一个能够实时监测并展示CPU占用率的点线图是一个实用的功能,尤其对于系统管理员和开发者来说,能快速了解服务器性能状态。本文将深入探讨如何实现这个小Demo,主要涉及的知识点包括ASP.NET...

    java小案例 firstcup

    java小案例 firstcupjava小案例 firstcup java小案例 firstcupjava小案例 firstcup java小案例 firstcupjava小案例 firstcup

    获取CPU占用率的代码

    以下是一个简单的示例代码片段,用于获取当前系统的CPU占用率: ```cpp #include #include #include #include double GetCPUPercentage() { PDH_HQUERY hQuery; PDH_HCOUNTER hCounter; PDH_FMT_COUNTER...

    Java获取计算机CPU、内存等信息

    在实际应用中,可以结合图形界面库(如JavaFX或Swing)创建一个实时的仪表盘来展示这些信息,就像描述中提到的"CPU使用率做了一个仪表图表"那样。这不仅可以帮助开发者调试程序,也可以为系统管理员提供实时的监控...

    WPF获取Windows系统内存占用和CPU占用

    在本文中,我们将深入探讨如何使用WPF(Windows Presentation Foundation)和Visifire库来实现一个功能,即实时监测并展示Windows操作系统的内存占用和CPU使用情况。Visifire是一款强大的数据可视化工具,它提供了...

    java-cup-11b-runtime-2015.03.26.jar

    java运行依赖jar包

    LALR(1)解析器的再工程: 剖析YACC和CUP

    从Yacc到CUP的转换不仅仅是简单的工具替换,更是一个深入理解LALR(1)解析器原理的过程。通过对Yacc和CUP的深入分析,我们可以更好地理解这两种工具之间的差异,并制定出有效的转换策略。这对于成功地将现有解析器...

    lexer and parser using jflex and cup

    1. **定义词法和语法**:首先,你需要编写两个规格文件,一个用于JFlex(定义词法规则),另一个用于CUP(定义语法规则)。 2. **生成Java代码**:运行JFlex和CUP工具,它们会根据规格文件自动生成Java源代码。 3. *...

Global site tag (gtag.js) - Google Analytics