한 편의 글 이 당신 을 데 리 고 JAVA 메모리 누 출 을 해결 합 니 다.

5416 단어 JAVA메모리 누설
1.메모리 누 출 이란 무엇 인가
메모리 누 출 이란 무용 대상(더 이상 사용 하지 않 는 대상)이 메모리 나 무용 대상 의 메모 리 를 지속 적 으로 점유 하거나 제때에 방출 하지 못 해 메모리 공간의 낭 비 를 메모리 누 출 이 라 고 한다.쓰레기 수 거 기 는 활동 이 증가 하고 메모리 사용량 이 증가 함 에 따라 프로그램의 성능 이 점점 떨 어 지고 극단 적 인 상황 에서 OutOf Memory Error 로 인해 프로그램 이 붕 괴 될 수 있 습 니 다.
2.메모리 누 출 의 원인
JVM 가상 머 신 은 인용 계수 법 과 접근 성 분석 을 이용 해 대상 의 회수 가능 여 부 를 판단 하 는 것 으로,본질은 한 대상 이 아직 인용 되 고 있 는 지 를 판단 하고 인용 되 지 않 으 면 회수 하 는 것 이다.개발 과정 에서 코드 의 실현 에 따라 여러 가지 메모리 누 출 문제 가 발생 하여 gc 시스템 이 이 대상 이 아직 인용 중이 라 고 착각 하여 회수 할 수 없 게 하여 메모리 누 출 을 초래 합 니 다.
3.메모리 누 출 상황
3.1 코드 에서 제때에 방출 되 지 않 아 메모리 가 회수 되 지 않 습 니 다.
아래 코드 는 양 방향 링크 이기 때문에 철저하게 끊 어 지지 않 았 습 니 다.prev 노드 는 현재 사용 하고 있 는 노드 를 참조 하여 회수 할 수 없습니다.

public class ListNode {
    int val;
    ListNode next;
    ListNode prev;
    ListNode() {
    }
    ListNode(int val) {
        this.val = val;
    }
    public ListNode(int val, ListNode next, ListNode prev) {
        this.val = val;
        this.next = next;
        this.prev = prev;
    }

    public static void main(String[] args) {
        ListNode curr = new ListNode(1);
        ListNode prev = new ListNode(2);
        ListNode next = new ListNode(3);
        curr.prev = prev;
        curr.next = next;
        curr.prev = null;
    }
}

    public static void main(String[] args) {
        ListNode curr = new ListNode(1);
        ListNode prev = new ListNode(2);
        ListNode next = new ListNode(3);
        curr.prev = prev;
        curr.next = next;
        curr.prev = null;
    }
}
3.2 자원 이 닫 히 지 않 아 발생 하 는 메모리 누 출
데이터베이스 연결,네트워크 연결,IO 연결 등 각종 연결,파일 읽 기와 쓰기 등 은 try-with-resources 로 파일 을 읽 고 자원 을 자동 으로 방출 할 수 있 습 니 다.

try (RandomAccessFile raf = new RandomAccessFile(filePath, "r");) {
        Image image = null;
while((image = parseImage(raf)) != null){
            imageList.add(image);
        }
        return imageList;
} catch(Exception e){
    log.error("parse file error, path: {},", path, e);
    return null;
}
3.3 전역 캐 시 에 있 는 대상 을 사용 하지 않 을 때 제거 하지 않 아 메모리 에서 제거 할 수 없습니다.
3.4 정적 집합 클래스
예 를 들 어 HashMap,LinkedList 등 이 있 습 니 다.이 용기 들 이 정적 이 라면 수명 주기 가 프로그램 과 일치 하면 용기 의 대상 은 프로그램 이 끝나 기 전에 방출 되 지 않 아 메모리 가 새 게 됩 니 다.라 이 프 사이클 이 긴 대상 은 짧 은 라 이 프 사이클 대상 의 인용 을 가지 고 있 습 니 다.짧 은 라 이 프 사이클 의 대상 은 더 이상 사용 하지 않 지만 긴 수명 주기 대상 이 인용 을 가지 고 있 기 때문에 회수 할 수 없습니다.
3.5 더미 외 메모리 회수 불가
외부 메모 리 는 gc 의 관 리 를 받 지 않 습 니 다.제3자 bug 로 인해 메모리 가 누 출 될 수 있 습 니 다.
4.메모리 누 출 의 해결 방법
1.정적 변 수 를 사용 하거나 제때에 값 을 null 로 할당 하 는 것 을 최소 화 합 니 다.
2.메모리 대상 의 효과 적 인 역할 도 메 인 을 명 확 히 하고 대상 의 역할 도 메 인 을 최대한 축소 하 며 국부 변수 로 처리 할 수 있 는 구성원 변 수 를 사용 하지 않 습 니 다.국부 변수 탄 스 택 은 자동 으로 회수 되 기 때 문 입 니 다.
3.수명 주기 가 긴 대상 이 짧 은 수명 주기 에 대한 인용 을 감소 합 니 다.
4.StringBuilder 와 StringBuffer 를 사용 하여 문자열 을 연결 합 니 다.Sting 과 StringBuilder,StringBuffer 등 은 문자열 을 대표 할 수 있 습 니 다.그 중에서 String 문자열 은 가 변 적 이지 않 은 문자열 을 대표 하고 그 다음 에 가 변 적 인 문자열 을 표시 합 니 다.여러 개의 String 대상 을 사용 하여 문자열 연결 연산 을 하면 실행 할 때 대량의 임시 문자열 이 생 길 수 있 습 니 다.이 문자열 들 은 메모리 에 저장 되 어 프로그램의 성능 이 떨 어 집 니 다.
5.사용 할 필요 가 없 는 대상 에 게 수 동 으로 null 값 을 설정 합 니 다.GC 가 언제 청 소 를 시작 하 든 저 희 는 쓸모없는 대상 을 청소 할 수 있 는 대상 으로 표시 해 야 합 니 다.
6.각종 연결(데이터베이스 연결,네트워크 연결,IO 연결)작업 은 반드시 호출 close 를 표시 해 야 합 니 다.
5.메모리 문제 조사
어떤 프로그래머 도 이런 문 제 를 일 으 키 려 고 하지 않 지만 문제 가 발생 해도 해결 해 야 한다.메모리 누 출 의 주요 이미 지 는 메모리 가 부족 하 다 는 것 이다.메모리 경고 후 메모리 누 출 여 부 를 어떻게 판단 하 느 냐 하 는 것 이다.
첫 번 째 단 계 는 먼저 논리 문 제 를 확인한다.
메모리 에 있 는 대상 의 수량 과 크기 를 보고 합 리 적 인 범위 에 있 는 지 판단 합 리 적 인 범위 내 에서 메모리 설정 을 확대 하고 메모리 비율 을 조정 하면 됩 니 다.
명령:
jmap -heap pid
图片
두 번 째 단계:gc 의 정상 적 인 실행 여 부 를 분석 합 니 다.
명령:
jstat -gcutil 1000
图片

S0 ― Heap   Survivor space 0               
S1 ― Heap   Survivor space 1               
E ― Heap   Eden space               
O   ― Heap   Old space               
P   ― Perm space           
YGC ―               Young GC    
YGCTC             Young GC      (   )    
FGC ―               Full GC    
FGCTC             Full GC      (   )    
GCT ―                      (   )
LGCC -   GC   (   jdk       )
여기 서 gc 의 이상 여 부 를 관찰 하고 이것 에 따라 jvm 메모리 분 배 를 조절 하여 성능 을 향상 시 켜 gc 의 성능 손실 을 낮 출 수 있 습 니 다.
세 번 째 단 계 는 다음 버 전에 추 가 된 코드 의 변경 을 확인 하고 가능 한 한 빨리 코드 에서 문 제 를 찾 아 냅 니 다.
STEP 4:각종 명령 행 을 열 고 dump 각종 도구 분석 내 보 내기

-XX:+HeapDumpOnOutOfMemoryError
-XX:OnError
-XX:+ShowMessageBoxOnError
jprofile 을 사용 하여 로 컬 분석 을 하 는 것 을 추천 합 니 다.그렇게 많은 명령 을 기억 하지 않 아 도 됩 니 다.
图片
요약:
현재 서버 메모 리 는 매우 크 지만 사용 하고 소 중 히 여 깁 니 다.문제 가 발생 할 때 까지 기 다 려 야 결 과 를 알 수 있 습 니 다.개발 과정 에서 자신의 코드 를 규범화 시 키 고 다 쓴 대상 을 제때에 방출 하여 쓰레기 대상 을 줄 이지 마 세 요.문제 가 생 겨 도 당황 하지 말고 코드 를 자세히 분석 하면 모든 것 이 원인 이 있다.
이 글 은 여기까지 입 니 다.당신 에 게 도움 을 줄 수 있 기 를 바 랍 니 다.또한 당신 이 우리 의 더 많은 내용 에 관심 을 가 져 주 기 를 바 랍 니 다!

좋은 웹페이지 즐겨찾기