最新的2017年热门编程语言排行榜已经出炉,java排名第一,纵观目前的市场,无论是IT金融软件服务行业或者云业务或大数据行业,java语言是开发的业务程序运用最广泛的语言之一。

本文主要通过分析云系统遭遇的java进程内存溢出的问题,介绍java进程占用系统内存高时的排查方案及建议的解决方案,同时延伸拓展java进程占用系统内存高的原因以及对于linux操作系统的内存管理和优化方案。

【云环境系统java进程内存占用高】

系统的运维值班人员发现该系统的uc注册页面访问超时,根据监控反馈的报错地址,登录相应的UC注册网页时,发现提示如下:网站维护中。

检查该uc注册业务对应的进程后,发现进程运行正常,检查服务的日志情况,然而并发现没有异常。

最后怀疑可能是该服务器的内存溢出,可能是产品对连接到服务端的线程没做控制,导致已结束、假死或超时的线程未释放内存,或者上述线程释放内存之后,没有进行内存整理,产生碎片,然后越积越大,然后就爆炸了。

但是查看服务器的内存情况如下:

通过以上查询发现,服务器内存总共4G,可用的还有300M左右,笔者查询相关资料后使用jmap -dump:format=b,file=ucweb.bin ${pid}的方法dump相应Java进程运行过程中占用的内存情况,然后导出为二进制文件,需要注意的是,这个对性能有影响,其中format=b是通过二进制的意思,通过这个命令把内存结构dump到二进制文件中,然后结合分析软件eclipse来获取具体情况。

也可以通过jmap –heap ${pid}命令来查看该java进程运行时所打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情况。

具体操作方法:

1、使用如下命令查看该业务进程的pid

2、使用jmap –heap 4665来查看该进程的具体使用情况如下:

其中详细描述了该进程的内存占用和配置情况:Heap Configuration是#堆配置情况、Heap Usage: ##堆使用情况、Eden Space: ##伊甸区、From Space: ##survior1区、To Space: ##survior2区、concurrent mark-sweep generation: ##老生代使用情况和Perm Generation: ##perm区使用情况。

▲使用ps命令也可以查看该进程的部分资源信息:

ps –p 4655 –o vsz,rss

从上面ps输出的VSZ和RSS分别是3.4G和0.67G,具体分析如下:VSZ是指已分配的线性空间大小,这个大小通常并不等于程序实际用到的内存大小,产生这个空间的可能性很多,比如内存映射,共享的动态库,或者向系统申请了更多的堆,都会扩展线性空间大小;RSZ是Resident Set Size,常驻内存大小,即进程实际占用的物理内存大小。

对于JVM的几个GC堆和GC也可以使用Jstat这个命令查看:

jstat -gcutil 4655 100 5

其中字段如下:

S0: 年轻代中第一个survivor(幸存区)已使用的占当前容量百分比。

S1: 年轻代中第二个survivor(幸存区)已使用的占当前容量百分比。

E: 年轻代中Eden(伊甸园)已使用的占当前容量百分比。

O: old代已使用的占当前容量百分比。

P: perm代已使用的占当前容量百分比。

YGC: 从应用程序启动到采样时年轻代中gc次数。

YGCT: 从应用程序启动到采样时年轻代中gc所用时间(s)。

FGC: 从应用程序启动到采样时old代(全gc)gc次数。

FGCT: 从应用程序启动到采样时old代(全gc)gc所用时间(s)。

GCT: 从应用程序启动到采样时gc用的总时间(s)。

通过以上显示结果得出此应用程序从启动到采样时具体的参数,如Perm space当前容量的大小和Perm space已经使用的大小,从而具体来定位是程序在进程运行时占用的内存大小,同时根据这个对该程序在启动的脚本catalina.sh中对的分配空间进行合理的配置:

JAVA_OPTS="-Xms1024m -Xmx2024m -XX:PermSize=128m -XX:MaxPermSize=256m"

最后通过进程的内存占用资源分析后:是由于永久代内存设置没生效,还是使用默认值,导致内存满了,然后触发fully gc。

【Java类程序的进程优化及处理方案】

结合以上的案例和分析,大致了解java进程异常时如何进行分析占用的内存和性能资源情况,这部分从java启动时的资源分配到运行时的详细性能跟踪及根据相应机器的配置合理分配对应的内存空间。

一.java进程在启动前的资源分配

只要接触过IT行业的人都知道“java进程运行时占用的内存很大”,很多程序员都有类似的遭遇,而且会认为运行Java程序时使用-Xmx和-Xms参数指定的就是程序将会占用的内存,但实际上只是Java堆对象占用的内存,堆只是影响Java程序占用内存数量的一个因素。要想了解java进程占用内存大的原因,可以先了解是哪些因素会影响到内存的占用。

大致来说,JAVA进程包含如下因素:对象(Objects)、类(Classes)、线程(Threads)、本地数据结构(Native data structures)、本地代码(Native code)。而且随着程序启动和运行后,上面的这些因素对内存占用的影响又实时根据应用程序、运行业务系统环境和不同的操作系统类型(windows、linux或mac)的不同而发生变化,因此该如何计算总的内存占用量?

想通过各种计算方式使用一个准确的数字是很困难的,因为程序员很难控制自己服务器上的特定参数,但是对照上面的影响因素能控制以下部分:

堆大小:-Xmx

类占用的内存:-XX:MaxPermSize

线程栈:-Xss控制每个线程占用的内存

Xmx是java进程启动的一个配置项,主要用于设置相应业务应用程序(不是整个jvm)运行时能够使用的最大内存数。如果该程序运行的服务器配置不高,但程序运行会占用很大内存时,那就需要修改缺省的设置;特别是配置tomcat的程序时,如果流量、程序都不低的话就需要修改这个缺省值。当然不要大得超过服务器的内存,否则就会出现程序一运行,服务器就挂掉的问题(内存爆掉);反之,如果这个值设置的比较低,每次运行的时候,就会出现内存不够的情况。

Xms是设置内存的另一个重要参数,用它来设置该程序进行初始化时所需要的内存栈的大小。增加这个值的话,程序的启动性能会得到提高。不过同样有前面的限制,并受到Xmx的限制。

XX:MaxPermSize设置过小会导致java.lang.OutOfMemoryError: PermGen space 会导致内存溢出。

▲内存溢出

1.这一部分内存用于存放Class和Meta的信息,Class在被Load时会放入PermGen space区域,它和存放Instance的Heap区域不同。

2.GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS 的话,就很可能出现PermGen space错误。

结合以上发现:一般情况下当栈设置的太小时会导致StackOverflow异常,程序出错。

计算内存占用情况的公式如下:

(-Xmx) + (-XX:MaxPermSize) + 线程数 * (-Xss) + 其它内存

其它内存取决于本地代码占用的内存,如NIO、socket缓冲区、JNI等。它一般大约是jvm内存的5%左右。

所以假设我们有下面的JVM参数和100个线程:

-Xmx1024m -XX:MaxPermSize=256m -Xss512k

因此在java程序启动的过程中,可以在启动脚本catalina.sh中定义如上参数的大小:

JAVA_OPTS="-Xms1024m -Xmx2024m -XX:PermSize=128m -XX:MaxPermSize=256m"

二.如何在JAVA运行过程中查看实时性能

结合以上部分对异常进程的分析和配置,可以了解到最常见的java进程性能资源的分析命令和具体的查看方式,下面大致介绍2种:Jmap和Jsata。

Jmap是一个java进程内存最常见的一个命令,它可以输出所有内存中对象的性能信息,特别是可以将VM 中的heap以二进制形式输出成文本file.bin。打印出指定Java进程(使用pid来区分)内存中的所有‘对象’的情况(如:产生那些对象,及其数量),然后使用分析软件eclipse或者其他的分析工具来分析输出的文本file.bin。

同样Jamp指令有不同的参数和具体的使用方式,这里只是简单说明一下。

例如该java进程的pid信息如下:

jmap –finalizerinfo 4655 -finalizerinfo 打印正等候回收的对象信息 。

jmap –heap 4655 -heap 打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情况。

jmap –histo 4655 -histo[:live] 打印每个class的实例数目,内存占用,类全名信息。VM的内部类名字开头会加上前缀”*”. 如果live子参数加上后,只统计活的对象数量。

jmap -permstat 4655 -permstat 打印classload和jvm heap永久代的信息,包含每个classloader的名字、活泼性、地址、父classloader和加载的class数量。另外,内部String的数量和占用内存数也会打印出来。

Jstat(Java Virtual Machine statistics monitoring tool)是JDK本身自带的一个轻量级小工具,目录一般在Java的bin下,主要利用JVM内建的指令对Java应用程序的资源和性能进行实时的命令行监控,也包括对Heap size和垃圾回收状况的监控。

Jstat的功能强大之处体现于众多的可选项,从而可以详细查看堆内各个部分的使用量以及加载类的数量,可以加上具体进程的id来查看相应的具体资源情况,这里也是简单说明一下。

jstat –class 4665 显示加载class的数量,及所占空间等信息。

jstat -compiler 4665 显示VM实时编译的数量等信息。

jstat -gc 4665 显示gc的信息,查看gc的次数和时间。

jstat -gccapacity 4655 显示VM内存中三代(young,old,perm)对象的使用和占用大小。

jstat -gcutil 4655 统计gc信息。

jstat -gcnew 4655 显示年轻代对象的信息。

jstat –gcold 4655 显示old代对象的信息。

jstat -gcoldcapacity 4655 显示old代对象的信息及其占用量。

jstat –gcpermcapacity 4655 显示perm对象的信息及其占用量。

jstat -printcompilation 4655 显示当前VM执行的信息。

JAVA性能优化,让程序更快更稳定相关推荐

  1. 性能优化:如何更快地接收数据

    从网卡到应用程序,数据包会经过一系列组件,其中驱动做了什么?内核做了什么?为了优化,我们又能做些什么?整个过程中涉及到诸多细微可调的软硬件参数,并且相互影响,不存在一劳永逸的"银弹" ...

  2. 笔记 :java性能优化 (from-JAVA程序性能优化)

    --From : JAVA程序性能优化 (葛一鸣,清华大学出版社,2012/10第一版) 1. java性能调优概述 1.1 性能概述  程序性能: 执行速度,内存分配,启动时间, 负载承受能力. 性 ...

  3. 服务器webpack构建性能,[译] 优化 WEBPACK 以更快地构建 REACT

    如果您的 Webpack 构建缓慢且有大量的库 -- 别担心,有一种方法可以提高增量构建的速度!Webpack 的 DLLPlugin 允许您将所有的依赖项构建到一个文件中.这是一个取代分块的很好选择 ...

  4. Java性能优化技巧

    Java性能优化技巧 参考了些书籍,网络资源整理出来,适合于大多数Java应用 在JAVA程序中,性能问题的大部分原因并不在于JAVA语言,而是程序本身.养成良好的编码习惯非常重要,能够显著地提升程序 ...

  5. 赠书:《Java性能优化实践》,众多业内大佬推荐阅读

    没有捷径可走的 Java 性能优化 多年来,用 Google 搜索 Java performance tuning,出现的三篇最热门文章之一是于 1997 年到 1998 年左右发表的文章,这篇文章在 ...

  6. 推荐:Java性能优化系列集锦

    Java性能问题一直困扰着广大程序员,由于平台复杂性,要定位问题,找出其根源确实很难.随着10多年Java平台的改进以及新出现的多核多处理器,Java软件的性能和扩展性已经今非昔比了.现代JVM持续演 ...

  7. java 性能 优化_Java十大简单性能优化

    java 性能 优化 关于" web scale "这个流行词有很多炒作,人们花了很多时间来重新组织他们的应用程序体系结构,以使其系统"规模化". 但是什么是扩 ...

  8. Java 性能优化的七个方向

    了解了优化目标后,那接下来应该从哪些方面入手呢?本文主要侧重于理论分析,我们从整体上看一下 Java 性能优化都有哪些可以遵循的规律.本文主讲理论.关于实践,后续的文章会用较多的案例来细化本文的知识点 ...

  9. 新书上市 | 《Java性能优化实践》,众多业内大佬推荐阅读

    没有捷径可走的 Java 性能优化 多年来,用 Google 搜索 Java performance tuning,出现的三篇最热门文章之一是于 1997 年到 1998 年左右发表的文章,这篇文章在 ...

最新文章

  1. 上交三月月赛[SJTU] 1106 sudoku
  2. [你必须知道的css系列]第一回:丰富的利器2:CSS选择符之子选择符、相邻选择符...
  3. python开发一个彩票系统_[宜配屋]听图阁
  4. 第一个Node.js实例
  5. 如何在CSMAR中找到不同公司,不同时间的数据呢?
  6. jquery ajax异步调用
  7. 处女座|处女座性格分析
  8. Extjs Grid 中给已经添加过Filter的列增加标识
  9. 10、Modules - LoadManual
  10. 小狼毫[rime_win][眀月拼音]简单配置方法
  11. Mac上制作Mac os10.12.6启动盘的多次尝试
  12. 五个拿来就能用的炫酷登录页面
  13. 《windows程序设计(C语言版)》笔记
  14. 判断两条直线的位置关系
  15. 爬取微博视频页并批量下载python+requests+ffmpeg(连接视频和音频)
  16. c语言两个矩形相交部分坐标,C++判断矩形相交的方法
  17. 绿色科技玩转冬奥会 电子垃圾铸奖牌
  18. 游码编程之Python代码应用
  19. 用户行为分析大数据平台之(一)项目介绍
  20. 主板有电无法启动_【主板不通电无法开机】主板不通电怎么修_主板通电但是开不了机...

热门文章

  1. 【建模算法】基于遗传算法求解TSP问题(matlab求解)
  2. XCTF simple-unpacked
  3. 鼠标事件(mouseover和mouseenter)
  4. c++中二维数组与二维向量的长度
  5. 欢迎使用Windows安装MySQL(安装版)教程,全网最细
  6. directives
  7. java项目中使用ffmpeg剪辑部分视频
  8. JSP Sessions
  9. 关于跨境支付,你了解多少
  10. 浅谈AI设计:理解玩家们对游戏的感知方式