LINUX类主机JAVA应用程序占用CPU、内存过高分析手段

简介:

转载声明:本文为DBA+社群原创文章,转载必须连同本订阅号二维码全文转载,并注明作者名字及来源:DBA+社群(dbaplus)。

 


做为一个IT运维人员,通常在运维过程中会遇到各种各样的问题,系统问题、应用问题、程序问题,而在这当中必然会涉及到性能问题,当用户量过大,或者服务器性能不足以支持大用户量,但同时又得不到扩容的情况下,进行性能分析,并对系统、应用、程序进行优化则显得尤为重要,同时也是节省资源的一种必不可少的手段,目前大多数的运维产品都是基于JAVA语言开发的,下面我给大家介绍一下在linux环境下对JAVA的性能分析手段。


1. 应用程序占用资源高问题


目前大部分应用程序采用的是JAVA语言开发,在产品上线使用一段时间后,经常会出现某个JAVA程序占用的CPU,内存过高,而且几乎从不释放,导致系统卡顿,用户使用变慢,如果要恢复,则必须杀掉该进程或重启该服务,然后进行此操作时,必定会导致业务中断。


程序主要由代码组成,优化则需要知道是哪段代码占用资源,并且一个应用占用CPU很高,除了确实是计算密集型应用之外,通常原因都是出现了死循环,所以通过优化代码来降低应用程序的资源消耗或者在应用的使用过程中减少死循环则必不可少。


下面我们以4A平台的字符网关服务器为例来进行相应分析。


2. 问题分析


2.1. CPU过高分析


1)使用TOP命令查看CPU、内存使用状态可以发现CPU占用主要分为两部分,一部分为系统内核空间占用CPU百分比,一部分为用户空间占用CPU百分比。其中CPU状态中标示id的为空闲CPU百分比。当空闲CPU百分比越低,说明CPU占用率越高。


2)初步分析可以发现其中主要占用CPU的进程为java子进程jerrySsh服务(用户访问资源使用的监听服务),在用户量不大的情况下,CPU消耗资源很大。根据研发反馈字符网关设定的最大访问量可达到500/台,目前字符网关的资源使用现状无法满足设定的要求。


● 分析手段


目前针对Linux下java进程占用CPU高的分析手段主要为使用linux命令查出高CPU使用的进程,前分析其是由于进程原因还是系统原因,在分析出为进程消耗过高CPU后列出占用CPU高和占用时间最长的线程并使用jdk自带的jstack工具进行分析CPU使用分析:

export JAVA_HOME=/usr/apps/java/jdk1.6.0_20/

export PATH=$JAVA_HOME/bin:$PATH

export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar


分析过程:

  1. 根据top命令,发现PID为13033的Java进程占用CPU %id 50%以上,占用CPU过高

  2. 找到该进程后,首先显示线程列表,并按照CPU占用高的线程排序:[root@YZ-A-ZFWG-4 ~]# ps -mp 13033 -o THREAD,tid,time | sort –rn


显示结果如下:



找到了耗时最高的线程28358,占用CPU时间达8分多钟。将需要的线程ID转换为16进制格式:[root@YZ-A-ZFWG-4 ~]# printf "%x\n" 28358

6ec6

最后打印线程的堆栈信息:




经比对发现占用CPU高的jerrySsh服务中高消耗CPU的代码均为一些等待和读取的语句。内核时间占用最长的线程所使用的代码抓取:



2.2. 内存使用分析


目前字符网关内存使用趋于平衡,除偶尔出现close_wait连接后由于未能得到及时释放而占用了大量内存导致buffers/cache较小外,其他线条暂未出现问题,据研发反馈已经做过优化,但是从目前观察来看coles_wait连接释放时间稍长。并且由于buffers、cached释放不出来,导致系统剩余物理内存较小,可能会影响系统性能,为了彻底解决此类问题,所以我们做了以下分析:



在linux的内存分配机制中,系统优先使用物理内存,当物理内存还有空闲,表示还够用时,不会释放其占用内存,即使占用内存的程序已经被关闭了,该程序所占用的内存用来做缓存使用,对于开启过的程序、或是读取刚存取过得数据会比较快,因此查看目前进程正在实际被使用的内存(used-buffers-cache),也可以认为如果交换分区(swap)没有大量使用,物理内存(mem)还是够用的,只有物理内存(mem)被当前进程实际占用完(没有了buffers和cache),才会使用到交换分区(swap)。


但是从代码的角度,目前研发人员主要关注java.lang.OutOfMemoryError: Java heap space异常,减少不必要的对象创建,同时避免内存泄漏,所以分析代码才是我们接下来要做的主要工作;以下为字符网关分析内存占用的故障排查过程:


● 分析手段

  1. top命令:Linux命令。可以查看实时的内存使用情况。  

  2. jmap -histo:live [pid],然后分析具体的对象数目和占用内存大小,从而定位代码。

  3. jmap -dump:live,format=b,file=xxx.xxx [pid],然后利用MAT工具分析是否存在内存泄漏。


Java提供了一个很好的内存监控工具:jmap命令

jmap命令有下面几种常用的用法:


从上述打印的日志可以得知该进程调系统进程占用内存的主要程序。


使用./jmap -histo:live 14978查询当前 Java进程创建的活跃对象数目和占用内存大小。


 


可以日志中发现constMethodKlass、methodKlass、symbolKlass都占用了大量的内存,特别是占用了大量内存的int数组,需要仔细检查相关代码,接下来这些事就可以丢给研发了。

3. 总结分析手段


● 分析CPU占用的方法和手段:

  1. top命令:可以查看实时的CPU使用情况。

  2. ps -ef命令:可以查看进程以及进程中线程的当前CPU使用情况以及属于当前状态的采样数据。

  3. jstack:Java提供的命令。可以查看某个进程的当前线程栈运行情况。根据这个命令的输出可以定位某个进程的所有线程的当前运行状态、运行代码,以及是否死锁等等。

  4. pstack:Linux命令。可以查看某个进程的当前线程栈运行情况


● 分析内存性能的方法和技巧:

  1. top命令:可以查看实时的内存使用情况。  

  2. jmap -histo:live [pid],然后分析具体的对象数目和占用内存大小,从而定位代码。

  3. jmap -dump:live,format=b,file=xxx.xxx [pid],然后利用MAT工具分析是否存在内存泄漏等等。



本文来自云栖社区合作伙伴"DBAplus",原文发布时间:2015-12-04

目录
相关文章
|
4天前
|
Arthas 存储 算法
深入理解JVM,包含字节码文件,内存结构,垃圾回收,类的声明周期,类加载器
JVM全称是Java Virtual Machine-Java虚拟机JVM作用:本质上是一个运行在计算机上的程序,职责是运行Java字节码文件,编译为机器码交由计算机运行类的生命周期概述:类的生命周期描述了一个类加载,使用,卸载的整个过类的生命周期阶段:类的声明周期主要分为五个阶段:加载->连接->初始化->使用->卸载,其中连接中分为三个小阶段验证->准备->解析类加载器的定义:JVM提供类加载器给Java程序去获取类和接口字节码数据类加载器的作用:类加载器接受字节码文件。
27 0
|
12天前
|
人工智能 安全 Java
Java并发包下Atomic相关类的使用
本文介绍了 `java.util.concurrent.atomic` 包下的各类原子类及其使用场景,包括基本类型原子类(如 `AtomicInteger`、`AtomicLong`)、数组类型原子类(如 `AtomicIntegerArray`)、引用类型原子类(如 `AtomicReference`)、对象属性修改原子类(如 `AtomicIntegerFieldUpdater`)以及原子操作增强类(如 `LongAdder` 和 `LongAccumulator`)。同时,详细对比了不同原子类在高并发场景下的性能表现,展示了 `LongAdder` 的高效性。
69 31
|
4天前
|
存储 安全 Java
【高薪程序员必看】万字长文拆解Java并发编程!(7):不可变类设计指南
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发编程中Java不可变类设计指南,废话不多说让我们直接开始。
15 0
|
1月前
|
Java 数据安全/隐私保护
Java 类和对象
本文介绍了Java编程中类和对象的基础知识,作为面向对象编程(OOP)的核心概念。类是对象的蓝图,定义实体类型;对象是具体实例,包含状态和行为。通过示例展示了如何创建表示汽车的类及其实例,并说明了构造函数、字段和方法的作用。同时,文章还探讨了访问修饰符的使用,强调封装的重要性,如通过getter和setter控制字段访问。最后总结了类与对象的关系及其在Java中的应用,并建议进一步学习继承等概念。
|
1月前
|
Java
java中一个接口A,以及一个实现它的类B,一个A类型的引用对象作为一个方法的参数,这个参数的类型可以是B的类型吗?
本文探讨了面向对象编程中接口与实现类的关系,以及里氏替换原则(LSP)的应用。通过示例代码展示了如何利用多态性将实现类的对象传递给接口类型的参数,满足LSP的要求。LSP确保子类能无缝替换父类或接口,不改变程序行为。接口定义了行为规范,实现类遵循此规范,从而保证了多态性和代码的可维护性。总结来说,接口与实现类的关系天然符合LSP,体现了多态性的核心思想。
42 0
|
2月前
|
Java
java常见的集合类有哪些
Map接口和Collection接口是所有集合框架的父接口: 1. Collection接口的子接口包括:Set接口和List接口 2. Map接口的实现类主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap以及 Properties等 3. Set接口的实现类主要有:HashSet、TreeSet、LinkedHashSet等 4. List接口的实现类主要有:ArrayList、LinkedList、Stack以及Vector等
|
9天前
|
数据可视化 Linux iOS开发
Python测量CPU和内存使用率
这些示例帮助您了解如何在Python中测量CPU和内存使用率。根据需要,可以进一步完善这些示例,例如可视化结果或限制程序在特定范围内的资源占用。
50 22
|
4月前
|
存储 设计模式 监控
快速定位并优化CPU 与 JVM 内存性能瓶颈
本文介绍了 Java 应用常见的 CPU & JVM 内存热点原因及优化思路。
770 166
|
2月前
|
存储 设计模式 监控
如何快速定位并优化CPU 与 JVM 内存性能瓶颈?
如何快速定位并优化CPU 与 JVM 内存性能瓶颈?
如何快速定位并优化CPU 与 JVM 内存性能瓶颈?
|
3月前
|
人工智能 运维 监控
2025年阿里云服务器配置选择全攻略:CPU、内存、带宽与系统盘详解
在2025年,阿里云服务器以高性能、灵活扩展和稳定服务助力数字化转型,提供轻量应用服务器、通用型g8i实例等多样化配置,满足个人博客至企业级业务需求。针对不同场景(如计算密集型、内存密集型),推荐相应实例类型与带宽规划,强调成本优化策略,包括包年包月节省成本、ESSD云盘选择及地域部署建议。文中还提及安全设置、监控备份的重要性,并指出未来可关注第九代实例g9i支持的新技术。整体而言,阿里云致力于帮助用户实现性能与成本的最优平衡。 以上简介共计238个字符。