JVM metaspace outofmemory

13143 단어

서버 프로세스 종료 문제 해결(metaspace 넘침)


.현상
  • 기획 반응 서버가 들어갈 수 없어서 원격으로 프로세스가 사라졌습니다(crash)
  • 때때로 로그인할 수 있지만 작업을 수행할 수 없습니다(프로세스가 아직 있습니다), 정상적으로 shutdown을 받을 수 없습니다
  • 프로세스 루트 디렉터리에java_pid16298.hprof 파일, 보기만 해도 메모리가 넘칩니다.
  • 이상하다고 생각하면 메모리가 넘치는 것은 아닐 것이다. 인원수가 많지 않기 때문에 영구구 넘치는 것으로 초보적으로 의심된다(Java8#Metaspace). 다음은 과연 검증되었다

  • - XX:+HeapDumpOnOutOfMemoryError가 시작 매개 변수에 추가되었습니다
  • hs_도 나왔어요.err_pid.log, 즉 JVM 치명적인 오류 로그입니다

  • 로그 조회(vim/grep/less/more)
  • vim std.log
  • esc/OutOfMemoryError ?OutOfMemoryError
  • n/N 다음

  • less std.log | grep OutOfMemoryError
  • Caused by: java.lang.OutOfMemoryError: Metaspace

  • grep OutOfMemory std.log -A 50 -B 50 | less
  • /OutOfMemoryError n 다음 q 종료

  • less std.log
  • 콜론/OutOfMemoryError 검색 q가 종료되어도 됩니까?OutOfMemoryError

  • more std.log
  • /OutOfMemoryError 검색 q 종료는/


  • 로그 출력에서 볼 때: Metaspace 메모리 넘침, 내 시작 파라미터 설정 크기는 48M
  • -XX:MaxMetaspaceSize=48m

  • 치명적인 로그의 출력을 보면 jvm가 Metaspace::allocate에서 치명적인 오류가 발생했습니다.
  • Metaspace used 47519K, capacity 48950K, committed 49152K, reserved 1093632K...
  • 유사한 로그를 볼 수 있는데 Metaspace가 거의 꽉 찼다는 것을 알 수 있다

  • why?
  • Metaspace 개념 이해
  • JVM 소스 분석의 Metaspace 복호화
  • java7과java8 중 일부는permgen에 있던 데이터가 더미로 옮겨졌습니다
  • JDK7부터 영구 세대 제거 작업을 시작하여 영구 세대에 저장된 데이터의 일부는 자바 힙이나 Native Heap로 옮겨졌다.그러나 영구대는 여전히 JDK7에 존재하고 완전히 제거되지 않았다. 기호 인용(Symbols)이native heap로 옮겨졌다.자면량(internedstrings)이javaheap로 이동;클래스의 정적 변수(classstatics)가javaheap로 옮겨졌습니다
  • In JDK 8, classes metadata is now stored in the native heap and this space is called Metaspace.

  • 어떤 공간이 점용되었는가(개인 분석은 주로 생성된 종류)
  • fastjson#asm(debug 디버깅을 통해)
  • deserializer
  • ASMDeserializerFactory#createJavaBeanDeserializer
  • JSON#parseObject(String text, Class clazz)와 같이 호출하면 fastjson ASMDeserializer_와 같은 clazz를 생성합니다53_xx류, 반서열화에 사용
  • 현재 사용되는 곳은 프로필, 데이터시트, 유저 관련 데이터 등을 포함한다

  • serializer
  • ASMSerializerFactory#createJavaBeanSerializer
  • JSON과 같이 호출할 때.toJSONString(Object object)은 ASMSerializer_와 같이 object#clazz와 대응하는1_xx류, write/서열화에 사용

  • 둘을 합치면 약 200개 정도

  • lambda 표현식 내부류
  • lambda 표현식을 사용하는 모든 곳에서 xx1과 같은 클래스가 약 150개 정도 생성됩니다

  • 프로토타입과 같은 다른 종류는 약 200여 개이다
  • 다른 것은 $의 내부 클래스를 보았지만 생성된 클래스와 같은 특별한 클래스는 발견되지 않았다
  • 숫자를 포함하는 클래스를 검색합니다. 일반적인 동적 생성의 유사성은 숫자 등이 있기 때문입니다.
  • 대량의 선이 발견되었다.reflect.GeneratedMethodAccessor344...
  • 약 350여 개가 발견되었고 같은 수의 선이 발견되었다.reflect.DelegatingClassLoader(클래스가 하나이고 해당 숫자만 있는 인스턴스)..
  • reflect.GeneratedConstructorAccessor...
  • 분석 - 반사 최적화, It can use a JNI accessor, or a Java bytecode accessor
  • JVM은 처음에 기본적으로 JNI 방식으로 호출되었는데, 같은 종류의 호출 횟수가 일정한 값에 도달하면 Java bytecode 호출로 바뀝니다

  • 반사 호출 방법에 대한log
  • 인터넷에는 이 메모리 넘침 문제로 인해 자체적으로 검색하여 볼 수 있는 내용이 많다

  • 현재 업무 논리에서 반사된 부분을 빈번하게 호출하고 있다.
  • handler 논리적 방법의 반사 집행
  • 프로토타입의 반서열화
  • 기타 삼방 라이브러리의 반사 등



  • 도구 사용
  • jvisualvm#hprof#플러그인 불러오기
  • 두 개의 hprof를 보면 7700여 개의 클래스를 불러올 때 메모리 넘침 오류가 발생했습니다
  • OQL 콘솔 # 오른쪽 아래 # 저장된 질의 # PermGen 분석 # 클래스 로더 유형
  • 재미있는 것을 발견했다. 대량의 xx143 같은 종류를 발견했다.
  • Lambda 표현식은 내부 클래스를 생성하는 것이다
  • 출력을 보면 Lambda 표현식으로 생성된 내부 클래스 번호는 1부터 시작하고++이다
  • 현재 보이는 것은 151개의 람다 내부류가 있다

  • 클래스 정보 아래에서 일치하는 것을 직접 검색할 수 있습니다

  • mat 사용하기
  • open heap dump
  • Size: 22.6 MB Classes: 7.5k Objects: 578k Class Loader: 357

  • JavaBasics#class loader explorer
  • 주요 몇 개의classloader#sun.misc.Launch$ExtClassLoader#defined class 4312
  • com.alibaba.fastjson.util.ASMClassLoader(Deserializer_)#129 > com.alibaba.fastjson.parser.deserializer.FastjsonASMDeserializer_53_xxConfig, 왜 모든 Config 대상이 반서열화된 내부 클래스를 생성했는지 확인해야 합니까?그리고 다른 xx_RedisConfig 등(fastjson#asm 원리를 이해하면 됨)
    com.alibaba.fastjson.serializer.ASMSerializer_70_xxConfig에서 코드를 봤는데 xxMonsterConfig가 하나 있었어요. 이것은 redis로 서열화할 때 Serializer Feature를 추가하지 않았어요.Ignore Non Field Getter, 서열화된 몬고의 플레이어는 이 기능을 통일적으로 추가했습니다.
  • system class loader#2617

  • 여기 설명 좀 해주세요.
  • 왜 이곳은 ExtClassLoader가 업무 중의 큰 분류를 불러왔습니다
  • 내 쪽 시동은 -Djava니까.ext.dirs=lib, 즉 AppClassLoader가 아닌 ExtClassLoader가 로드됩니다


  • 둘 다 OQL 사용 가능
  • OQL Syntax
  • SELECT DISTINCT OBJECTS classof(s) FROM "com.xx.*"s
  • 조회 대상이 속하는 클래스는com에 있습니다.xx 싸라
  • 대략 600여 개가 있다




  • 총결과 해결 방법
  • 위에서 분석한 바와 같이 메타스페이스가 분배한 공간이 너무 적고 48M이 128M으로 조정된 후 실제 달리기 테스트를 준비해야 한다
  • Lambda 표현식은 내부 클래스를 생성합니다
  • 반사 호출이 잦은 JVM도 해당 클래스를 생성합니다


  • .총결산-2017.9.28
  • 프로세스crash의 대가가 매우 크기 때문에 비교적 큰metaspace를 설정할 수 있지만 누설되면 프로세스가 직접crash에 영향을 미칠 수 있다.
  • 그래서 이 파라미터를 설정하지 않고 jvm가 스스로 조절하는 것을 권장합니다.만약 정말 유출이 발생한다면, 메모리는 줄곧 미친 듯이 길어질 것이다
  • 이때 우리의 운영 모니터링 시스템은 감청할 수 있다. 즉시 경보를 하고 정상적인 shutdown(shutdown 전에 jmap hprof)을 걷고 문제를 조사할 수 있다
  • ps:Out Of Memory crash 때 shutdownhook를 실행합니다. 하지만 프로세스가 갑자기 crash되면 유저 체험에 영향을 주고 유실을 초래할 수 있습니다


  • std.log
  • Caused by: java.lang.OutOfMemoryError: Metaspace
            at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.8.0_40]
            at java.lang.ClassLoader.defineClass(ClassLoader.java:760) ~[na:1.8.0_40]
            at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[na:1.8.0_40]
            at java.net.URLClassLoader.defineClass(URLClassLoader.java:467) ~[na:1.8.0_40]
            at java.net.URLClassLoader.access$100(URLClassLoader.java:73) ~[na:1.8.0_40]
            at java.net.URLClassLoader$1.run(URLClassLoader.java:368) ~[na:1.8.0_40]
            at java.net.URLClassLoader$1.run(URLClassLoader.java:362) ~[na:1.8.0_40]
            at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_40]
            at java.net.URLClassLoader.findClass(URLClassLoader.java:361) ~[na:1.8.0_40]
            at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_40]
            at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_40]
    
  • hs_err_pid.log
  • Stack: [0x00007f03927ff000,0x00007f0392900000],  sp=0x00007f03928fe340,  free space=1020k
    Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
    V  [libjvm.so+0xaaca9a]  VMError::report_and_die()+0x2ba
    V  [libjvm.so+0x4f2de9]  report_fatal(char const*, int, char const*)+0x59
    V  [libjvm.so+0xab3d6a]  VMThread::execute(VM_Operation*)+0x2ca
    V  [libjvm.so+0x47ecf0]  CollectorPolicy::satisfy_failed_metadata_allocation(ClassLoaderData*, unsigned long, Metaspace::MetadataType)+0x150
    V  [libjvm.so+0x8928c5]  Metaspace::allocate(ClassLoaderData*, unsigned long, bool, MetaspaceObj::Type, Thread*)+0x315
    V  [libjvm.so+0x8a5a26]  MethodCounters::allocate(ClassLoaderData*, Thread*)+0x26
    V  [libjvm.so+0x89d811]  Method::build_method_counters(Method*, Thread*)+0x71
    V  [libjvm.so+0x8a01f0]  BreakpointInfo::set(Method*)+0x3a0
    V  [libjvm.so+0x796cd6]  JvmtiBreakpoint::each_method_version_do(void (Method::*)(int))+0x56
    V  [libjvm.so+0xab5ac5]  VM_Operation::evaluate()+0x55
    V  [libjvm.so+0xab3e9a]  VMThread::evaluate_operation(VM_Operation*)+0xba
    V  [libjvm.so+0xab421e]  VMThread::loop()+0x1ce
    V  [libjvm.so+0xab4690]  VMThread::run()+0x70
    V  [libjvm.so+0x910ee8]  java_start(Thread*)+0x108
    
  • javavisualvm#정보를 불러옵니다
  •   : Mon Sep 25 14:30:30 CST 2017
         : D:\xx\landon\task\2017.9\server_err\java_pid16298.hprof
         : 56.1 MB
    
         : 47,508,830
         : 7,743
         : 568,577
         : 380
         : 2,703
         : 0
    
          OutOfMemoryError  
          OutOfMemoryError  : queue-executor-handler-8
    
  • lambda$
  • com.xx.achilles.spurs.gs.model.combat.CombatService$$Lambda$143
    com.xx.achilles.spurs.gs.model.raid.daily.DailyRaidManager$$Lambda$142
    com.xx.achilles.spurs.gs.model.daily.DailyManager$$Lambda$141
    ...
    
  • mat#class loader explorer
  • Class Name                                           | Defined Classes | No. of Instances
    ------------------------------------------------------------------------------------------
    sun.misc.Launcher$ExtClassLoader @ 0x800230b0        |           4,312 |           93,289
                                    |           2,617 |          484,122
    com.alibaba.fastjson.util.ASMClassLoader @ 0x805fd848|             129 |              129
    com.alibaba.fastjson.util.ASMClassLoader @ 0x805e2858|              73 |               73
    ------------------------------------------------------------------------------------------
    ...
    
  • sun.reflect.GeneratedMethodAccessor
  • Class Name                                               | Shallow Heap | Retained Heap
    ----------------------------------------------------------------------------------------
    class sun.reflect.GeneratedMethodAccessor344 @ 0x80593e18|            0 |           568
    class sun.reflect.GeneratedMethodAccessor343 @ 0x80593ee0|            0 |           568
    class sun.reflect.GeneratedMethodAccessor342 @ 0x80593fa8|            0 |           568
    class sun.reflect.GeneratedMethodAccessor341 @ 0x80594070|            0 |           568
    class sun.reflect.GeneratedMethodAccessor340 @ 0x80594138|            0 |           568
    class sun.reflect.GeneratedMethodAccessor339 @ 0x80594200|            0 |           568
    class sun.reflect.GeneratedMethodAccessor338 @ 0x805942c8|            0 |           568
    class sun.reflect.GeneratedMethodAccessor337 @ 0x80594390|            0 |           568
    class sun.reflect.GeneratedMethodAccessor336 @ 0x80594458|            0 |           568
    ...
    ----------------------------------------------------------------------------------------
    
    
  • sun.reflect.DelegatingClassLoader
  • Class Name                                                     | Defined Classes | No. of Instances
    ----------------------------------------------------------------------------------------------------
    sun.misc.Launcher$ExtClassLoader @ 0x800230b0                  |           4,312 |           93,289
                                              |           2,617 |          484,122
    com.alibaba.fastjson.util.ASMClassLoader @ 0x805fd848          |             129 |              129
    com.alibaba.fastjson.util.ASMClassLoader @ 0x805e2858          |              73 |               73
    javax.management.remote.rmi.NoCallStackClassLoader @ 0x806fc4f8|               1 |                0
    javax.management.remote.rmi.NoCallStackClassLoader @ 0x806fc5d0|               1 |                0
    sun.reflect.DelegatingClassLoader @ 0x80593db8                 |               1 |                1
    sun.reflect.DelegatingClassLoader @ 0x80593e80                 |               1 |                1
    sun.reflect.DelegatingClassLoader @ 0x80593f48                 |               1 |                1
    sun.reflect.DelegatingClassLoader @ 0x80594010                 |               1 |                1
    sun.reflect.DelegatingClassLoader @ 0x805940d8                 |               1 |                1
    sun.reflect.DelegatingClassLoader @ 0x805941a0                 |               1 |                1
    sun.reflect.DelegatingClassLoader @ 0x80594268                 |               1 |                1
    sun.reflect.DelegatingClassLoader @ 0x80594330                 |               1 |                1
    sun.reflect.DelegatingClassLoader @ 0x805943f8                 |               1 |                1
    sun.reflect.DelegatingClassLoader @ 0x805944c0                 |               1 |                1
    sun.reflect.DelegatingClassLoader @ 0x80594588                 |               1 |                1
    sun.reflect.DelegatingClassLoader @ 0x80594650                 |               1 |                1
    sun.reflect.DelegatingClassLoader @ 0x805947c8                 |               1 |                1
    sun.reflect.DelegatingClassLoader @ 0x80594890                 |               1 |                1
    sun.reflect.DelegatingClassLoader @ 0x80594958                 |               1 |                1
    sun.reflect.DelegatingClassLoader @ 0x80594a20                 |               1 |                1
    sun.reflect.DelegatingClassLoader @ 0x80594ae8                 |               1 |                1
    sun.reflect.DelegatingClassLoader @ 0x80594bb0                 |               1 |                1
    sun.reflect.DelegatingClassLoader @ 0x80594c78                 |               1 |                1
    sun.reflect.DelegatingClassLoader @ 0x80594d40                 |               1 |                1
    ----------------------------------------------------------------------------------------------------
    
    

    좋은 웹페이지 즐겨찾기