메모리 넘침의 원인과 해결 방법

4859 단어 Java 기반

1. 넘쳐흐른다


이런 장면은 가장 흔히 볼 수 있는데 정보를 잘못 보고한다.
java.lang.OutOfMemoryError: Java heap space

까닭
1. 코드에 큰 대상 분배가 존재할 수 있다. 2. 메모리 유출이 존재하기 때문에 GC를 여러 번 사용한 후에도 현재 대상을 수용할 충분한 메모리를 찾을 수 없다.
해결 방법
1. 큰 대상의 분배가 존재하는지 검사한다. 가장 가능성이 있는 것은 대수조 분배 2이다. jmap 명령을 통해 메모리 덤프를 내리고 mat 도구를 사용하여 메모리 누출이 존재하는지 분석한다. 3. 뚜렷한 메모리 누출을 찾지 못하면 -Xmx를 사용하여 메모리 덤프를 확대한다. 4, 그리고 무시되기 쉽다. 대량의 사용자 정의finalizable 대상이 있는지 검사하면 프레임 내부에서 제공할 수도 있다.그 존재의 필요성을 고려하여 저의 공종호[프로그래머 추풍]를 주목해 주신 것을 환영합니다. 글은 모두 안에 업데이트되고 정리된 자료도 안에 넣을 것입니다.

2. 영구대/원 공간 넘침


오류 메시지:
java.lang.OutOfMemoryError: PermGen spacejava.lang.OutOfMemoryError: Metaspace

영구 세대는 HotSot 가상 기기가 방법 영역에 대한 구체적인 실현으로 가상 기기에 불러오는 클래스 정보, 상수, 정적 변수, JIT가 컴파일한 코드 등을 저장한다.
JDK8 이후 메타 공간이 영구 세대로 바뀌었고 메타 공간은 로컬 메모리를 사용했으며 다른 세부 사항도 변경되었습니다.
문자열 상수가 영구적으로 무더기로 이동합니다
및 영구 세대 관련 JVM 매개변수가 제거됨
가능한 원인은 다음과 같습니다.
1、Java7 이전에 빈번한 오류로 String을 사용했습니다.intern () 방법 2. 실행 기간에 대량의 프록시 클래스가 생성되어 방법 구역이 터져서 마운트 해제할 수 없습니다. 3. 장시간 실행되고 다시 시작하지 않았습니다.
JVM 프로세스를 다시 시작하지 않은 경우 일반적으로 디버깅이 수행됩니다. 예를 들어 다음 tomcat 홈페이지의 FAQ 참조:
Why does the memory usage increase when I redeploy a web application? That is because your web application has a memory leak. A common issue are “PermGen” memory leaks. They happen because the Classloader (and the Class objects it loaded) cannot be recycled unless some requirements are met (). They are stored in the permanent heap generation by the JVM, and when you redeploy a new class loader is created, which loads another copy of all these classes. This can cause OufOfMemoryErrors eventually. (*) The requirement is that all classes loaded by this classloader should be able to be gc’ed at the same time.
해결 방법
이 OOM의 원인은 비교적 간단하기 때문에 해결 방법은 다음과 같다.
1. 영구 세대 공간 또는 메타 공간 설정의 과소 여부를 확인한다. 2. 코드에 대량의 반사 조작이 존재하는지 확인한다. 3. dump 이후 mat를 통해 반사로 인해 생성된 대량의 프록시 클래스가 존재하는지 확인한다. 4, 확대기, JVM 재부팅
v2-b26a29f62e69256653075aa6e05ce75d_hd.png

3.GC overhead limit exceeded


이 이상한 비교의 보기 드문 오류 메시지:
java.lang.OutOfMemoryError:GC overhead limit exceeded

까닭
이것은 JDK6가 새로 추가한 오류 유형입니다. 일반적으로 너무 작게 쌓아서 발생합니다.GC를 만드는 데 98% 가 넘는 시간을 사용하고 2% 도 안 되는 메모리를 회수할 때 이 이상을 던집니다.
해결 방법
1. 프로젝트에 대량의 사순환이 있거나 큰 메모리를 사용하는 코드가 있는지 확인하고 코드를 최적화한다.
2. 파라미터 추가 -XX:-UseGCOverheadLimit은 이 검사를 사용하지 않습니다. 사실 이 파라미터는 메모리 문제를 해결하지 못하고 잘못된 정보를 미루면 최종적으로java가 발생합니다.lang.OutOfMemoryError: Java heap space.
3. Dump 메모리, 메모리 유출이 있는지 확인하고 없으면 메모리를 늘린다.

4. 메소드 스택 오버플로우


오류 메시지:
java.lang.OutOfMemoryError : unable to create new native Thread

까닭
이런 이상이 발생한 것은 기본적으로 모두 대량의 라인을 만들어서 발생한 것이다. 이전에 한 번 만났는데 jstack를 통해 모두 8000여 개의 라인이 나왔다.
해결 방법
1. -Xss를 통해 감소된 스레드 스택 크기의 용량 2. 스레드 총수도 시스템의 빈 메모리와 운영체제의 제한을 받는다. 이 시스템에 이런 제한이 있는지 확인한다.
/proc/sys/kernel/pid_max
/proc/sys/kernel/thread-max
maxuserprocess(ulimit -u)
/proc/sys/vm/maxmapcount

5. 일반 오버플로우


아래의 OOM 이상은 대부분 학우들이 만나지 못했을 수도 있지만, 그래도 좀 알아야 한다.
분배 초대수 그룹
오류 메시지:
java.lang.OutOfMemoryError: Requested array size exceeds VM limit

일반적으로 잘못된 배열 할당 요청으로 인해 JVM은 배열에 메모리를 할당하기 전에 체크를 수행합니다.분배할 그룹이 이 플랫폼에서 주소를 찾을 수 있는지 (addressable) 여부입니다. 주소를 찾을 수 없으면 이 오류가 발생합니다.
해결 방법은 코드에 초대형 그룹을 만드는 곳이 있는지 확인하는 것이다.
v2-7daa361860ef4ee83a6f1748a71a04d4_hd.png

6.swap 오버플로우


오류 메시지:
java.lang.OutOfMemoryError: Out of swap space

이러한 상황은 일반적으로 운영 체제에 의해 발생하는데 가능한 원인은 다음과 같다.
1. swap 구역 크기 분배 부족;
2. 다른 프로세스는 모든 메모리를 소모했다.
솔루션:
1. 다른 서비스 프로세스는 선택적으로 분리할 수 있다. 2. swap 구역의 크기를 늘리거나 기계 메모리의 크기를 늘릴 수 있다.

7. 로컬 메서드 오버플로우


오류 메시지:
java.lang.OutOfMemoryError: stack_trace_with_native_method 로컬 방법은 실행할 때 메모리 분배 실패가 발생했습니다. 이전의 방법 창고 넘침과 달리 방법 창고 넘침은 JVM 코드 차원에서 발생했고 로컬 방법 넘침은 JNI 코드나 로컬 방법에서 발생했습니다.
이 이상이 나타날 확률은 매우 낮아서 운영체제의 로컬 도구를 통해서만 진단할 수 있기 때문에 난이도가 좀 크니 포기하는 것이 좋다.

좋은 웹페이지 즐겨찾기