자바 언어는 때때로 다음 메모리에주의를 지불하는 것입니다 마법의 장소가있다. (물론, 어떤 Niubi 학생들은 메모리에 대한 걱정해야)
그것은 오늘 우리는거야 장면을 수 있도록 : 응용 프로그램이 잠시, ECS 알람 모니터링을 실행하고, 메모리가 상대적으로 높은되면 어떻게합니까? 시간이 지남에 따라 점점 더 많은 메모리를 (하지만 100 %에 충돌하지 않습니다) 발견, 어떻게 할까?
증거에 대한 모든 경찰은, 신경 긴장 메모리를했다 테스트 할 자신이있다.
어떻게 메모리 문제를 확인하기 위해? 이것은 너무 중요하다! 여기에 메모리 문제점을 확인할 수있는 몇 가지 방법이 있습니다 :( 사랑) 그 여부를 아 믿거
시스템 메모리 정보 등 1. 평면도
상단 : 메모리는 메모리 크기 분류에 따라 M에 따르면, 이동, 즉시 범인을 참조하십시오. 특정 명령 줄 정보를 참조하시기 바랍니다.
다음과 같이 상단 잠시 사용
형식을 사용하여 : 상위 [ - ] [D] [P] [Q] [C] [C] [S] [S] [N-] 파라미터 : D : 각각의 사이의 시간이 두 배 간격 정보 화면을 새로 지정. 물론, 사용자는이를 변경할의 대화 형 명령을 사용할 수 있습니다. p는 : 단지 모니터링 프로세스 ID를 지정하여 프로세스의 상태를 모니터링한다. Q :이 옵션은 상단 어떤 지체없이 새로 고칠 수 있습니다. 호출자가 수퍼 유저 권한이있는 경우, 상단은 가능한 가장 높은 우선 순위가 될 것입니다. S는 : 축적 모드를 지정합니다. S : 상단 명령은 안전 모드에서 실행합니다. 이것은 잠재적으로 위험한 대화식 명령이 제공 제거합니다. 내가 : 상단은 유휴 또는 좀비 프로세스를 표시하지 않습니다. C : 그냥 명령 이름을 표시하는 대신 전체 명령 줄을 보여줍니다. 일반적으로 명령 설명을 사용 : Ctrl 키를 +의 L : 지우고 화면 다시 K를 : 프로세스를 종료 할 수 있습니다. 이 시스템은 전송 될 필요가 신호의 어떤 종류 프로세스 PID를 종료 할 수있는 사용자 및 프로세스 메시지가 표시됩니다. 종료 프로세스는 일반적으로 15 신호를 사용할 수 있습니다, 당신은 강제로 프로세스를 종료가 제대로 9의 끝을 사용할 수없는 경우. 디폴트 값은 신호 (15)이다. 보안 모드 명령에서 보호됩니다. 내가 : 유휴 좀비 프로세스를 무시합니다. 이 스위칭 명령이다. Q : 프로그램 종료 R을 : 프로세스의 우선 순위를-배열 재. 이 시스템은 프로세스 PID 및 우선 순위 값을 설정해야 할 필요성을 변경하라는 메시지를 표시. 그렇지 않으면 프로세스가 더 높은 우선 순위를 가질 수 있습니다, 우선 순위를 낮출 양의 값을 입력합니다. 기본값은 10입니다. S : 축적 모드로 전환합니다. S :이 새로 고침 사이의 지연 시간을 변경합니다. 이 시스템은의에, 새로운 시간을 입력하라는 메시지가 표시됩니다. 소수가 있다면, 그것은 MS로 변환됩니다. 입력 0 값, 시스템이 새로 고침 계속해서, 기본값은 5 초입니다. 시간 설정이 너무 작은 경우, 끊임없이 새로 고침으로 이어질 가능성이 있습니다, 그래서 시간은 디스플레이 케이스를 볼 수 없습니다하고, 시스템 부하가 크게 증가 할 것이다. F 또는 F : 추가하거나 현재 화면에서 항목을 제거합니다. 또는 O O : 디스플레이 항목의 순서 변경 L : 평균 부하 및 표시 개시 시각 정보를 전환한다. m : 디스플레이 메모리 전환 정보. t : 표시 처리와 CPU의 상태 정보를 전환. C : 표시 이름과 전체 명령 줄 명령을 전환합니다. M : 메모리 상주 크기에 따라 분류. P : 분류 크기의 CPU에 따라 비율을 사용. T : 시간 / 시간 정렬이 축적된다. W : 현재 설정 쓰기 ~ / .toprc 파일을.
또한 메모리보기의 관점에서, 당신은 또한, 당신은 시스템 캐시 얼마나 많은 볼 수있는 빠른 직시 무료 메모리를 사용할 수 있습니다 (일반적으로 실제 사용되는 시스템 캐시 메모리에 포함되지 않음)
2. 항목을 신속에게의 JVM 메모리 예외를 찾을 JMX
JMX를 열 경우 JMX는, 우리가 jvisualvm 메모리를 통해 직접 볼 수, 스레드가 상황을 모니터링, 당신은 또한 다른 JMX 지표를 볼 수 있습니다,
당신이 그렇게에 메모리, 가비지 컬렉션, CPU 동향의 추세를 볼 수 있습니다 여기에서, 직관적 많이 문제는이 부분에서 찾을 수 있습니다.
또한 발견 된 코드에서 CPU와 메모리 수집 모드 초크 포인트를 수집 할 수 있습니다.
우리의 코드 최적화 매개 변수를 JMX 또는 도구의 절대 왕을 과대 평가라고 할 수있다.
성능 문제를 신속하게 병목 지점을 찾기 위해 적절한 CPU / 메모리 샘플링하실 수 있습니다!
제안 된 새로운 플러그인 :
Btrace 작업대 원격 디버깅을 위해 유용 할 수있다;
BufferMonitor 用于查看堆外内存情况,其实可能不准;
Threads Inspector 用于快速查看各线程情况;
VisualJVM-MBeans 用于查看 jmx 暴露出来的 指标信息,可作为业务监控使用;
3. jmap dump 详细分析jvm的内存使用情况
jmap dump,发现内存过,其他方面没啥思路,那就jvm内存dump下来,慢慢分析。
dump整个内存下来,全量分析,jmap -dump:format=b,file=/tmp/a.dump . 然后就可以使用jvm内存分析工具进行分析了,如 mat 。分析工具的技巧可能还是需要去掌握下的,不过我这里简单提两个点,一个就是看得到的堆内存,一个不可达的堆内存,分析时就注意这两点。一般可达堆内存是很好分析的,不可达堆内存则要凭借一定的经验才能发现问题了。
对于快速查询,则直接在服务器上使用 jmap -heap 就可以查看了。
jmap -dump:format=b,file=/tmp/a.dump <pid> # dump倒是堆内存 jmap -heap <pid> # 直接在服务器上查看堆的使用情况
4. lsof 列举出正在使用的文件,看看是否能发现一些端倪
lsof,这个工具用于排查是否存在很在很多超出预料的文件的情况,比如打开某文件未关闭,建立很多的socket连接等等。当然,发现问题只能靠眼力劲了。
lsof -p <pid> #查看进程打开的文件情况。
lsof 使用详细介绍参考网上资料: https://www.cnblogs.com/sparkbj/p/7161669.html
5. pmap 查看进程内存概要
pmap,用于查看进程的内存映像信息, 发现内存中大块的占用所在,以及分析内存可能存在的异常。
从中,你可以看到哪些内存上面占用了多少内存,正常的内存如 JVM 所在内存段,应该是和你的堆内存一致的,而其他内存段,则是你看不到的地方,这些地方将是你排查内存泄漏的方向。
简要命令下: pmap [ -x | -d ] [ -q ] pids... 结果样例如下: [root@abtest ~]# pmap -x 27466 27466: /usr/local/jdk1.8.0_211/bin/java -Dzookeeper.log.dir=. -Dzookeeper.root.logger=INFO,CONSOLE -cp /opt/zookeeper/zookeeper-3.4.14/bin/../zookeeper-server/target/classes:/opt/zookeeper/zookeeper-3.4.14/bin/../build/classes:/opt/zookeeper/zookeeper-3.4.14/bin/../zookeeper-server/target/lib/*.jar:/opt/zookeeper/zookeeper-3.4.14/bin/../build/lib/*.jar:/opt/zookeeper/zookeeper-3.4.14/bin/../lib/slf4j-log4j12-1.7.25.jar:/opt/zookeeper/zookeeper-3.4.14/bin/../lib/slf4j-api-1.7.25.jar:/opt/zookeeper/zookeeper-3.4.1 Address Kbytes RSS Dirty Mode Mapping 0000000000400000 4 4 0 r-x-- java 0000000000600000 4 4 4 r---- java 0000000000601000 4 4 4 rw--- java ... 00007fff10253000 136 36 36 rw--- [ stack ] 00007fff102ce000 8 4 0 r-x-- [ anon ] ffffffffff600000 4 0 0 r-x-- [ anon ] ---------------- ------- ------- ------- total kB 5421732 100608 87672
命令操作详情请参考网上资料:: https://www.cnblogs.com/txw1958/archive/2012/07/26/linux-pmap.html
6. NMT, nativeMemoryTracking jvm 的内存追踪工具
nmt,这个jdk8以后,jvm提供的内存跟踪工具,nativeMemoryTracking, 可以用于排查内存方案的问题。
-XX:NativeMemoryTracking=summary # 开启NMT追踪 jcmd 1 VM.native_memory summary # 查看当前的内存概况 jcmd 1 VM.native_memory baseline # 创建基准 baseline jcmd 1 VM.native_memory summary.diff # 一段时间后,比对内存差异,可以用于发现内存的走向问题,如下 [root@abtest ~]# jcmd 5545 VM.native_memory summary.diff 5545: Native Memory Tracking: Total: reserved=5942859KB +2339KB, committed=4104347KB +1519KB - Java Heap (reserved=4194304KB, committed=3645440KB) (mmap: reserved=4194304KB, committed=3645440KB) - Class (reserved=1109328KB +2056KB, committed=66640KB +264KB) (classes #11172 +2) (malloc=1360KB +8KB #15153 +331) (mmap: reserved=1107968KB +2048KB, committed=65280KB +256KB) - Thread (reserved=133119KB, committed=133119KB) (thread #130) (stack: reserved=132544KB, committed=132544KB) (malloc=422KB #652) (arena=152KB #256) - Code (reserved=255919KB +247KB, committed=37519KB +1219KB) (malloc=6319KB +247KB #8248 +270) (mmap: reserved=249600KB, committed=31200KB +972KB) - GC (reserved=209075KB +8KB, committed=188707KB +8KB) (malloc=20659KB +8KB #28406 +320) (mmap: reserved=188416KB, committed=168048KB) - Compiler (reserved=277KB +5KB, committed=277KB +5KB) (malloc=146KB +5KB #592 +9) (arena=131KB #6) - Internal (reserved=12648KB, committed=12648KB) (malloc=12616KB #39090 +5) (mmap: reserved=32KB, committed=32KB) - Symbol (reserved=16444KB +8KB, committed=16444KB +8KB) (malloc=12569KB +8KB #121265 +2) (arena=3876KB #1) - Native Memory Tracking (reserved=3362KB +15KB, committed=3362KB +15KB) (malloc=18KB #204 +2) (tracking overhead=3344KB +15KB) - Arena Chunk (reserved=192KB, committed=192KB) (malloc=192KB) - Unknown (reserved=8192KB, committed=0KB) (mmap: reserved=8192KB, committed=0KB)
如上结果,我们可以得得出些结论,随着时间的推移, code 部分的占用空间增加了最多(JIT), Compiler 也增加一些,而堆内存则一直保持不变!
7. perf,这是一个性能监控调优工具,但是我们也可能从中发现内存问题点
可以先捕获数据,然后进行性能分析,然后得到可疑的点。
帮助信息如下:
usage: perf [--version] [--help] [OPTIONS] COMMAND [ARGS] The most commonly used perf commands are: annotate Read perf.data (created by perf record) and display annotated code archive Create archive with object files with build-ids found in perf.data file bench General framework for benchmark suites buildid-cache Manage build-id cache. buildid-list List the buildids in a perf.data file c2c Shared Data C2C/HITM Analyzer. config Get and set variables in a configuration file. data Data file related processing diff Read perf.data files and display the differential profile evlist List the event names in a perf.data file ftrace simple wrapper for kernel's ftrace functionality inject Filter to augment the events stream with additional information kallsyms Searches running kernel for symbols kmem Tool to trace/measure kernel memory properties kvm Tool to trace/measure kvm guest os list List all symbolic event types lock Analyze lock events mem Profile memory accesses record Run a command and record its profile into perf.data report Read perf.data (created by perf record) and display the profile sched Tool to trace/measure scheduler properties (latencies) script Read perf.data (created by perf record) and display trace output stat Run a command and gather performance counter statistics test Runs sanity tests. timechart Tool to visualize total system behavior during a workload top System profiling tool. probe Define new dynamic tracepoints trace strace inspired tool See 'perf help COMMAND' for more information on a specific command.
简单示例:
perf record -g -e cpu-clock -p 5545 # 记录进程 5545 的相关性能信息 perf report -i perf.data # 读取刚刚记录的数据,可以显示出种操作的占用情况,如下 Samples: 908 of event 'cpu-clock', Event count (approx.): 227000000 Children Self Command Shared Object Symbol + 32.27% 0.00% java libpthread-2.17.so [.] start_thread + 32.27% 0.00% java libjvm.so [.] java_start + 26.54% 0.00% java libjvm.so [.] ConcurrentG1RefineThread::run + 26.54% 0.11% java libjvm.so [.] ConcurrentG1RefineThread::run_young_rs_sampling + 25.77% 5.62% java libjvm.so [.] YoungList::rs_length_sampling_next + 22.58% 0.55% java [kernel.kallsyms] [k] tracesys + 11.01% 0.00% java perf-5545.map [.] 0x00007f553ec1e981 + 10.79% 0.44% java libjvm.so [.] JVM_Sleep + 9.36% 0.55% java libjvm.so [.] G1CollectorPolicy::update_incremental_cset_info + 8.70% 0.55% java libjvm.so [.] os::sleep + 8.26% 0.00% java [unknown] [k] 0xee83b0ac00709650 + 8.15% 0.99% java libpthread-2.17.so [.] pthread_cond_timedwait@@GLIBC_2.3.2 + 7.93% 0.00% java perf-5545.map [.] 0x00007f553f7f7d30
如果运气碰巧的话,你有可能能查到某些异常的操作,从而推断出问题所在。
8. gdb 调试工具dump出可疑内存
gdb, linux下强大的调试工具,但是我们不用它来调试,我们只用来输出内存的内容。即dump内存,前面用到的jmap dump只能看到jvm的内存信息,而gdb则可以看所有的,当然我们会用来看其他部分的内存。
gdb attach <pid> # 先连接到进程中 gdb dump memory /path/dump.bin 0x0011 0x0021 # dump 出内存段的信息,具体要 dump 的内存段地址,可以借助之前pmap 排查的结果,以及 cat /proc/<pid>/maps 中指示的地址段得出 strings /path/dump.bin | less # 查看内存内容, 相信你能从中发现一些不一样的东西
以上,足够你排查出你怀疑的内存泄露问题了。如果不能,那就算了!
唠叨: 注重时效性!