자바 : 온라인 문제 해결 기존의 수단 수 (rpm)

출처 :  자바 : 온라인 문제 해결의 일반적인 수단

 

A는 대용량 메모리 풋 프린트의 예를 찾을 수있는 jmap

샘플 코드를 제공 :

수입 인 java.util.ArrayList;
수입 은 java.util.List;
수입 java.util.concurrent.CountDownLatch; 
 
/ ** 
 * 2017년 5월 9일에菩提树下的杨过작성. 
 * / 
공용  클래스 OOMTest { 
 
    공공  정적  무효 메인 (문자열 [] 인수)이 발생 예외 : InterruptedException { 
        CountDownLatch를 래치 = 새로운 CountDownLatch를 (1 );
        INT 최대 = 10000 ; 
        목록은 <사람> 목록 = 새로운 ArrayList를을 <> (최대);
         ( INT J = 0; J <최대, J ++ ) {
            인 (P) = 새로운 인 (); 
            p.setAge ( 100 ); 
            p.setName ( "菩提树下的杨过" ); 
            에는 list.add (p); 
        } 
        에서 System.out.println ( "준비!" ); 
        latch.await (); 
    } 
 
 
    공공  정적  클래스 사람 {
         개인 문자열 이름;
        개인  INT의 시대; 
 
        공공 문자열 getName () {
             반환 이름; 
        } 
 
        공공  무효 에서는 setName (문자열 이름) {
             .name과는 = 이름; 
        } 
 
        공공  INT getAge () {
             반환 시대; 
        } 
 
        공공  무효 setAge ( INT의 연령) {
              .age = 나이; 
        } 
    } 
}

예 목록이 프로그램을 넣고 실행 Person 객체를 넣어 1W

javac의 OOMTest.java

자바 OOMTest

그리고 창을 열고 는 -l을 JPS  프로그램의 PID를 찾을 수

 

 그리고 할 수 있는 jmap -histo을 : 라이브 7320 (참고 : 내용의 출력이 너무 많이, 단지 10를보고 싶다면, 당신은 추가 할 수 있습니다 | 머리 -10)

 

 

출력 메모리 사용하여 것, 오브젝트, 내림차순 (바이트) 메모리의 양을 차지의 실제 수는 될 최종 출력의 요약을 출력 할

위의 예에서,이 클래스 10000 OOMTest $ 이용시의 경우의 수는 240,000 바이트의 총 차지 (주 : 각 인스턴스, 즉 24 바이트), 점유 프로그램 메모리의 총 수는 약 725,464 바이트이다 0.69 M.

아마 의미 일부 [C, [B 같은 클래스 이름도있다 :

  [C는 숯불 []는
  [S 짧은 []은
  [I는 INT는이 []은
  [B는 바이트 []은
  [I는 INT이다 [] []

[String 오브젝트와 C는 종종 문자열을, 데이터를 유지하기 위해 그 내부 마지막 문자 [] 배열 관련

constMethodKlass / methodKlass / constantPoolKlass / constantPoolCacheKlass / instanceKlassKlass / methodDataKlass

관련 클래스 로더, 주민과 페름 지역.

 

둘째,? 스레드 및 핸들 자바 애플리케이션 개방의 수를 찾으려면

LL 은 / proc / PID} {/ FD | WC는 -l 볼 열린 핸들 번호

LL / proc 디렉토리 / {PID는} / 태스크 | WC는 -l은 스레드의 수를 볼 수 있습니다

 

세, 힙 메모리의 구성을 볼 수있는 jmap

jmap는 -heap PID 다음과 같은 출력과 같은 것을 볼 수 :

스레드 국부적하여 개체 . 할당 
GC와 병렬 . 4 실 (S)   // 본 실시 GC (GC 평행 한)이 사용될 
 
: 힙 구성   // 힙 메모리 구성 
   MinHeapFreeRatio = 0    // 대응 JVM 기동 파라미터 -XX : MinHeapFreeRatio 배치 JVM 스택 최소 유휴 비율 (java8 디폴트 0) 
   MaxHeapFreeRatio = 100  // 대응 JVM 기동 파라미터 -XX : MaxHeapFreeRatio 최대 유휴 JVM 스택 비율 설정 
   maxHeapSize = 8,388,608 ( . 8 .0MB)를 // 대응 JVM 기동 파라미터 -XX : maxHeapSize = JVM 스택 구비 최대 크기 (또는 -Xmx 파라미터) 
   newSize와 = 5,242,880 ( . 5 .0MB) //JVM -XX 대응 시작 파라미터 : newSize와 배치 = JVM 스택 '차세대'기본 
   MaxNewSize = 5,242,880 ( . 5 .0MB) // 대응 JVM 기동 파라미터 -XX : MaxNewSize = 배치 JVM 스택 '차세대'최대 크기 
   OldSize = 3,145,728 ( 3. .0MB) // 대응 JVM 기동 파라미터 -XX : OldSize = 배치 JVM 스택 '구세대'크기 
   NewRatio = 2  // 대응 JVM 기동 파라미터 -XX : NewRatio = '차세대'와 '이전 소년 세대 '크기 비율 
   SurvivorRatio = 8.  // 대응 JVM 기동 파라미터 -XX : SurvivorRatio = 에덴 젊은 세대 영역 크기 면적비 배치 서바이버 
   MetaspaceSize = 21,807,104 ( 20 .796875MB) 
   CompressedClassSpaceSize =1073741824 ( 1024 .0MB) 
   MaxMetaspaceSize          = 17,592,186,044,415 MB 
   G1HeapRegionSize          = 0 ( 0 .0MB) 
 
힙 사용법 : // 힙 메모리 사용 
의 PS 젊은 세대 
에덴 공간 : // 에덴의 유통 영역 
   용량 = 2,621,440 ( 2 .5MB) // 에덴 지역 총 용량이 
   사용되는 = 2,328,088 ( 2 .2202377319335938MB) // 에덴 영역이 사용 
   무료      = 293 (352) ( 0 .27976226806640625MB)를 //용량에게 남아있는 에덴 지역 
   88.80950927734375 %는 사용 
우주에서을 : // 항에있어서, 생존자 메모리 유통 영역 
   용량 = 1,572,864 ( . 1 .5MB) 
   사용      = 360 (448) ( 0 .34375MB)
    무료      = 1,212,416 ( . 1 .15625MB)
    22.916666666666668 % 사용 
받는 공간 : /을 / 메모리 레이아웃 영역 다른 서바이버 
   용량 = 1048576 ( . 1 .0MB) 
   사용      = 0 ( 0 .0MB)
    무료      =1,048,576 ( . 1 .0MB)
    0.0 % 사용 
의 PS 구세대 // 현재 메모리 영역 분포 오래 
   용량 = 3,145,728 ( . 3 .0MB) 
   사용      = 1,458,968 ( . 1 .3913803100585938MB)
    무료      = 1,686,760 ( . 1 .6086196899414062MB)
    46.37934366861979 % 사용한 
 
3759 구금 문자열 점령 298 824 바이트를.

참고 : 라인 5-16 힙 메모리는 기본 구성이며, 이러한 매개 변수 수있는 자바 -XX 수 : 같은 이름의 매개 변수 값, 매개 변수 크기 조정 =를 :

자바 -XX : MinHeapFreeRatio -XX = 20 : 80 = MaxHeapFreeRatio -Xmx100m -XX : MetaspaceSize = 50M -XX : NewRatio = 3 将 影响 MinHeapFreeRatio, MaxHeapFreeRatio, MaxHeapSize, MetaspaceSize, NewRatio 的 值

참고 NewRatio는,이 값이 오래된 년 (올드 세대)로 참조하는 : 새로운 세대 (젊은 세대) 3 위의 비율은 다음 그림을 참조하여, 25m에 OldSize의 75m 정도로 배열되고, newSize와있다 :

참고 :이 jdk7 개략도이다, jdk8 영구 세대가 제거 된, 새로운 기능 Metaspace 영역에 진입하지만, 새로운 세대는 이전 세대의 이해에 영향을주지 않습니다 차이.

새로운 세대 (젊은 세대) 에덴, S0, S1 세 블록으로 세분화 할 수있다.

Java7 실질적으로도되는 메모리 변경 java8.

SurvirorRatio는 좀 더 열심히 계산이 A는 오라클의 공식 웹 사이트에 따르면 설명 : https://docs.oracle.com/cd/E19159-01/819-3681/abeil/index.html  , 기본 값, 즉 :? 각각의 생존자 8 : 에덴 영역의 크기는 1 : 8, 환언 S0 = S1 = 1 / (1 + 1 + 8) = 1/10

참고 : 공식 웹 사이트는 이렇게 설명하지만, 내 진짜 문제는,이 수에 엄격하게 비례하지 않는다 보이지만, 아마이 할당 비율이라고 할 수있다. (결론은 : 큰 SurvirorRatio 설정, 큰 에덴 영역)

 

넷째, 가장 높은 점유율 스레드 CPU를 찾을 수

코드의 데모에 먼저 :

import java.util.concurrent.CountDownLatch;
 
/**
 * Created by 菩提树下的杨过 on 05/09/2017.
 */
public class OOMTest {
 
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(1);
        int max = 100;
        for (int i = 0; i < max; i++) {
            Thread t = new Thread() {
                public void run() {
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                }
            };
            t.setName("thread-" + i);
            t.start();
        }
        Thread t = new Thread() {
            public void run() {
                int i = 0;
                while (true) {
                    i = (i++) / 10;
                }
            }
        };
        t.setName("BUSY THREAD");
        t.start();
        System.out.println("ready");
        latch.await();
    }
 
}

这里面有100个线程是空转的,另外还有一个线程BUSY THREAD在狂跑CPU。

javac OOMTest.java

java OOMTest

把程序跑起来,jps -l 找出pid,然后  top -Hp pid

 

 

可以看到pid 16813这个对应的线程,把CPU快跑满了,达到了98.5%

接下来,将16813转换成16进制 ,即41ad (tips: printf "%x" 16813 ) ,然后

jstack pid | grep '41ad'

我们就把最忙的这个线程BUSY THREAD给找出来了(注:这个技巧再次说明了,给线程取个好名字相当重要!)

tips:如果使用spring-boot的话,直接在浏览器里查看/dump端点,也可以达到类似jstack的效果。

 

五、jvisualvm 查看运行情况

JDK_HOME/bin下有一个自带的jvisualvm工具,可以图形化的查看GC情况(注:要安装插件)

java.net这个网站已经被oracle关了,所以安装插件这里,有点小麻烦,先到https://visualvm.github.io/pluginscenters.html 这里找到jvisualvm对应的jdk版本号,以jdk8为例,地址就是 https://visualvm.github.io/uc/8u131/updates.xml.gz

然后,把这个地址在Plugins里的Settings里改一下,然后Available Plugin这里,就能看到可用插件了,选择GC插件并安装。

원본을 보려면 클릭하세요

可以来一段代码,然后用jvisualvm来看下GC情况

import java.util.ArrayList;
import java.util.List;
 
/**
 * Created by 菩提树下的杨过 on 05/09/2017.
 */
public class OOMTest {
 
    public static void main(String[] args) throws InterruptedException {
        List<String> list = new ArrayList<>();
        while (true) {
            Thread.sleep(10);
            list.add("菩提树下的杨过" + System.currentTimeMillis());
        }
    }
}

可以直观的看到Old区,Eden区,S0,S1以及Metaspace区的内存变化情况,以上图为例:Old Gen区占用内存一直在增加,表示可能有内存一直未被释放,值得关注。

此外,还可以看到占用内存最多的类(即:本文最开始提到的)

원본을 보려면 클릭하세요

还可以更进一步点击看详情,比如下面的图,就能发现Metaspace已经OOM了

원본을 보려면 클릭하세요

 

也可以查看哪些线程最忙

원본을 보려면 클릭하세요

 

六、使用jstat 查看GC

虽然jvisualvm很好用,但是通常服务器是用终端连上的,无法运行图形化界面,而且也并非所有应用都开启了jmx,所以掌握jstat以命令行方式查看GC情况也是蛮重要的

用法:jstat -gc pid 采样间隔毫秒数,比如: jstat -gc 8544 5000,将每隔5s采样一次pid为8544的gc情况

以上图为例:红剪头的地方,S0区的已用量降到0,而S1区的已用量上涨,即说明发生了Young GC,对象从S0区被迁移到了S1区。

title栏的含义如下:

S0C - 新生代中第1块survivor 的容量(Survivor 0 Capacity),KB单位
S1C - 新生代中第2块survivor 的容量(Survivor 1 Capacity),KB单位 
S0U - 新生代中第1块survivor 已使用空间数(Survivor 0 Used),KB单位 
S1U - 新生代中第2块survivor 已使用空间数(Survivor 0 Used),KB单位 
EC - Eden区的容量(KB) 
EU - Eden区已使用(KB数) 
OC - Old区的容量(KB) 
OU - Old区已使用(KB数) 
MC - Metaspace容量(KB) 
MU - Metaspace已使用KB 
CCSC - 压缩类的内存容量(KB)
CCSU - 压缩类的已用容量(KB) 
YGC - (从应用启动算起,到采样时的) Young GC次数 
YGCT - (从应用启动算起,到采样时的) Young GC所用时间(秒) 
FGC - (从应用启动算起,到采样时的) Full GC次数 
FGCT - (从应用启动算起,到采样时的) Full GC所用时间(秒) 
GCT - (从应用启动算起,到采样时的) Yong GC + Full GC的总时间

值得一提的是G1垃圾回收器,在大堆(>4G)时,用G1可能效果会更好,G1的开启方法:

-XX:+UseG1GC -XX:MaxGCPauseMillis=200 

켜져 때, 사용 jmap는 -heap PID 

기본 동시 GC는 G1되고에서 우리는 볼 수 있습니다.

그러면 jstat -gc PID 5000

S0은 G1의 특징은 본 명세서의 마지막 참조하여 설명 된대로 새로운 세대, 분할 이전의 시대를 해제하지만, 영역의 새로운 개념과 함께, 전체 힙 메모리를 하나 개의 영역으로 분할되는 것 인, 모두 0을 참조 기사.

 

세븐, 전체 JVM의 수출 덤프

jmap의 -dump : B = 포맷, 파일 이름 = [PID]

내보낼 때이 최후의 수단이어야 확대, 전체 JVM은 다른 모든 수단이 작동하게되면 일반적으로 만 운영 및 유지 보수, 대량 내 보낸 파일에 참여할 것을 발견, 분석을 설정하고 응용 프로그램을 일시 중지됩니다 . 이 파일이 지역 얻을 후, 당신의 플러그인 일식 사용할 수있는 매트 : 다운로드 주소 분석 http://www.eclipse.org/mat/downloads.php을

 

추천

출처www.cnblogs.com/myseries/p/11854917.html