当前位置: 首页 > 后端技术 > Java

使用top命令分析java程序占用内存

时间:2023-04-02 00:25:24 Java

psaux命令执行结果几列信息的含义USER进程所属用户的PIDProcessID%CPUCPU占用百分比bytheprocess%MEM进程占用的内存百分比VSZ虚拟内存占用大小单位:kb(killobytes)RSS实际内存大小单位:kb(killobytes)TTY终端类型STAT进程状态START进程启动时间TIME进程运行时间,进程已消耗CPUtimeCOMMAND启动进程的命令的名称和参数进程,包括进程使用的库、代码、数据等2.如果进程申请了100m内存,但实际只使用了10m,那么会增加100m,而不是实际使用量RES:常驻内存usage常驻内存1、进程当前使用的内存大小,但不包括swapout2、与其他进程共享3、申请100m内存,实际使用10m,只增加10m,与VIRT相反4、关于库占用的内存,只统计加载的库文件占用的内存大小SHR:sharedmemorySharedmemory1.除了自身进程的内存Sharedmemory,包括其他进程的sharedmemory2.虽然进程只使用了几个共享库函数,包含了整个共享库的大小3.进程占用物理内存大小的计算公式:RES-SHR4,换出后会减少DATA1占用的内存和数据。如果未显示顶部,请按f键显示它。2、程序真正需要的数据空间是在运行时实际使用的。top运行时,可以通过top内部命令控制进程的显示方式。内部命令如下:s–改变屏幕更新频率l–关闭或打开第一部分第一行top信息的显示t–关闭或打开第一部分中Tasks和Cpus信息的显示第一部分第二行m–关闭或打开第一部分Mem第四行和Swap信息显示第五行N–按照PID大小的顺序排列进程列表P–按照顺序排列进程列表ofCPUusagesizeM–按照内存使用大小的顺序排列进程列表h–显示帮助n–设置进程列表中显示的进程数q–退出tops–更改屏幕更新周期序列号列名含义PID进程idbPPID父进程idcRUSER名为UID的真实用户进程所有者的用户ideUSER进程所有者的用户名fGROUP进程所有者的组名gTTY启动进程的终端的名称。不是从终端启动的进程显示为?hPRPriorityiNInicevalue。负值表示高优先级,正值表示低优先级。jP最后使用的CPU,只在多CPU环境下有意义。k%CPU自上次更新以来占用的CPU时间百分比lTIME进程使用的CPU总时间,单位为秒mTIME+进程使用的CPU总时间,单位为1/100秒n%MEM的percentageofphysicalmemoryusedbytheprocessoVIRT进程使用的虚拟内存总量,单位是kb。VIRT=SWAP+RESpSWAP进程使用的虚拟内存中,换出的大小以kb为单位。qRES进程使用但未换出的物理内存大小,以kb为单位。RES=CODE+DATArCODE可执行代码占用的物理内存大小,单位kbsDATA除可执行代码(数据段+栈)以外部分占用的物理内存大小,单位kbtSHR共享内存大小,单位kbunFLT缺页次数vnDRT的自上次写入以来已修改的页数。wS进程状态。(D=不间断睡眠状态,R=running,S=sleeping,T=tracking/stopping,Z=zombieprocess)xCOMMAND命令名/命令行yWCHAN如果进程处于睡眠状态,显示睡眠中的系统函数名zFlags任务标志,参考sched.h默认只显示PID、USER、PR、NI、VIRT、RES、SHR、S、%CPU、%MEM、TIME+、COMMAND等重要列。可以通过以下快捷键更改显示内容。可以用f键选择显示的内容。按f键后会显示一列列,按a-z显示或隐藏相应列,最后按回车键确认。按o键更改列的显示顺序。小写的a-z将相应的列向右移动,大写的A-Z将相应的列向左移动。最后按回车键确认。按大写的F或O键,然后按a-z按相应列对进程进行排序。大写R键可以反转当前排序。jmapcommandjmap-heapprocessIDAttachingtoprocessID17775,pleasewait...Debuggerattachedsuccessfully.Servercompilerdetected.JVMversionis25.121-b13usingthread-localobjectallocation.ParallelGCwith2thread(s)parallelconcurrentgarbagecollectorHeapConfiguration:MinHeapFreeRatio=0MaxHeapFreeRatio=100MaxHeapSize=1006632960(960.0MB)当前JVM最大堆大小NewSize=20971520(20.0MB)MaxNewSize=335544320(320.0MB)OldSize=41943040(40.0MB)NewRatio=2SurvivorRatio=8MetaspaceSize=21807104(20.796875MB)当前元空间大小CompressedClassSpaceSize=1073741824(1024.0MB)MaxMetaspaceSize=17592186044415MB元空间最大大小G1HeapRegionSize=0(0.0MB)HeapUsage:PSYoungGenerationEdenSpace:capacity=25165824(24.0MB)used=15424152(14.709617614746094MB)free=9741672(9.290382385253906MB)61.29007339477539%从空间中使用:容量=1572864(1.5MB)使用=1013016(0.9660873413085938MB)免费=559848(0.53391265869126586914062MB)(1.5MB)0.0%usedPSOldGenerationcapacity=84934656(81.0MB)used=62824456(59.91407012939453MB)free=22110200(21.08592987060547MB)73.96798781406733%usedps命令ps-p进程ID-ovsz,rssVSZRSS3701784413924VSZ是指已分配的线性空间的大小。这个大小通常不等于程序实际使用的内存大小。这有很多种可能,比如内存映射,共享动态库,或者向系统申请更多的堆,这些都会扩大线性空间大小RSZ为ResidentSetSize,常驻内存大小,即进程pmap命令实际占用的物理内存大小pmap-xprocessIDAddressKbytesRSSDirtyModeMapping0000000000400000440r-x--java0000000000600000444rw---JAVA0000000000017F80002325R216216---[ANON]00000000C400000082944634886348863488RW---[ANON]00000000C91000005724165724160000-----[ANON]----anon]......totalkB3701784413924400716Address:内存分配地址Kbytes:实际分配内存大小RSS:程序实际占用内存大小mmap分配的JAVA应用程序内存分析JAVA进程内存=JVM进程内存+堆内存+永久代内存+本地方法栈内存+线程栈内存+堆外内存+socket缓冲内存+元空间VIART=JAVA中请求的内存大小,即-Xmx-Xms+other=永久代内存+本地方法栈内存+线程栈内存+堆外内存+socket缓冲内存+JVM进程内存JVM内存模型(1.7和1.8的区别))求和可知,前者一共为Java环境分配了128M内存,而ps输出的VSZ和RSS分别为3615M和404M。RSZ和实际堆内存相差276M。内存组成部分是:JVM自身需要的内存,包括它加载的第三方库和这些库分配的内存。NIO的DirectBuffer是分配的nativememory内存映射文件,包括JVM加载的一些JAR和第三方库,还有程序内部使用的。上面pmap输出的内容中,一些静态文件占用的大小在Java堆中并不是JIT的。JVM会把Class编译成native代码,内存不会少。如果使用Spring的AOP,CGLIB会生成更多的class,JIT的内存开销也会增加JNI,一些JNI接口调用的nativelibraries也会分配一些内存。如果在JNI库中遇到内存泄漏,可以使用valgrind等内存泄漏工具检测线程栈。每个线程都有自己的堆栈空间。如果有多个线程,这个开销会很明显1MB)pshuHpProcessID|wc-lps-LfProcessID|wc-ltop-H-pProcessIDcat/proc/{pid}/statusjmap/jstack采样,频繁采样也会增加内存占用,如果有Server健康监控,这个频率需要控制几个GC堆和jstat的GC命令JVM,可以用jstat监控,比如监控一个进程每1000毫秒刷新一次,输出20次jstat-gcutilprocessID100020S0S1EOMCCSYGCYGCTFGCFGCTGCT0.0039.5895.6374.6698.3596.938154.00230.3314.3330.0039.5895.7674.6698.3596.938154.00230.3314.33341.670.001.6274.6798.3596.938164.00630.3314.33741.670.001.6774.6798.3596.938164.00630.3314.33741.670.003.1274.6798.3596.938164.00630.3314.33741.670.003.1274.6798.3596.938164.00630.3314.33741.670.008.3974.6798.3596.938164.00630.3314.33741.670.009.8574.6798.3596.938164.00630.3314.337S0年轻代中第一个survivor(幸存区)已已使用的当前容量百分比S1年轻代中第二个幸存者(生存区)使用的当前容量百分比E年轻代中伊甸园使用的当前容量百分比oldgenerationPpermgeneration占用当前容量的百分比YGC应用启动到采样时间在younggeneration中的gc次数YGCT应用在younggeneration中GC使用的时间(s)startuptothesamplingtime(s)FGC从应用启动到oldgeneration(fullgc)中的采样时间(samplingtime)gctimesFGCT从应用启动到oldgeneration(fullgc)gc(s)使用的采样时间(s)GCT从应用程序启动到采样的总时间(s),一般情况下gc用来总结jmap输出的内存占用比RSZ小很多,所以不用太担心,除非出现一些严重的错误,比如PermGen空间满了发生OutOfMemoryError,或者RSZ太高,引起系统公愤被OOMKiller杀掉,你要注意了,是时候加内存了,加内存,没钱买内存加swap空间,或者根据上面列出的组件一一排除这些内存指标之间的关系:VSZ>>RSZ>>Java程序实际使用的堆大小转载自:https://www.jianshu.com/p/479…