2010-08-04 11 views
14

JProfilerEclipse Tptp. 을 사용하여 Java 응용 프로그램의 작업장 프로파일 링, 성능 조정, 메모리 프로파일 링, 메모리 누출 감지 등을 수행하려고합니다. 제공 할 수있는 연습 세트가 필요합니다. 참여자에게 : 이 도구를 사용하여 병목 현상, 메모리 누출, 차선의 코드 등 문제를 파악할 수 있습니다. 많은 경험과 실제 예가 있습니다. Java 프로파일 링, 성능 튜닝 및 메모리 프로파일 링

  • 이상적으로 프로파일의 다른 세션을 수행하여 솔루션을 시연 최적화 된 코드를
  • 을 문제를 해결하고 구현, 성능 향상을

문제도 해결 방법을 보여줍니다 단위 테스트를 안 쓰기 지나치게 복잡하다; 기껏해야 몇 분 만에 문제를 해결할 수 있어야하고 최악의 경우 몇 시간 만에 문제를 해결할 수 있어야합니다. 어떤 흥미있는 분야는 운동하기 :

  • 해결 메모리가
  • 최적화 동시성 및 동시성에 의해 악화
  • 최적화 객체 생성 및 관리
  • 최적화 된 문자열 작업
  • 해결 문제 병목 현상을 루프 누수

연습 문제에는 최적화되지 않은 샘플 코드가 포함되어야합니다. 솔루션 코드.

+1

물론 자료를 요청하고 있습니까? –

+0

은 더 정확하게 연습합니다. 나는 그들을 워크샵에서 사용하고 싶지만 이것들이 자바 애플리케이션을 튜닝하고 프로파일 링하는 사람들에게 흥미가있을 것이라고 말하고 싶다. – Dan

+4

VisualVM을 다른 두 언어와 함께 사용하는 것이 좋습니다. 시간이 문제라면 JProfiler를 제외하십시오. JProfiler는 꽤 매끄럽지 만 사람들이 프로파일 링 할 수있을 정도의 도구이기 때문에 비용을 지불하지 않고도 사람들을 프로파일 링 할 수 있습니다. 그리고 솔직히 말하면, 다른 두 개는 일반적으로 병목 현상과 교착 상태를 찾기에 충분합니다. –

답변

6

야생에서 본 실제 사례를 찾으려고합니다. (약간 변경되었을 수도 있지만 기본적인 문제는 모두 매우 현실적이었습니다). 또한 동일한 시나리오를 중심으로 클러스터링하려고 했으므로 세션을 쉽게 구축 할 수 있습니다.

시나리오 : 다른 값에 대해 여러 번 수행하려는 많은 시간이 소요되는 기능이 있지만 동일한 값이 다시 표시 될 수 있습니다 (이상적으로 생성 된 후 너무 오래 걸리지는 않음). 좋고 간단한 예는 다운로드하고 처리해야하는 URL 웹 페이지 쌍입니다 (실제로 시뮬레이트해야하는 운동의 경우).

루프 :

  • 당신은 단어의 집합의 어떤 페이지에 팝업 있는지 확인하고 싶습니다. 루프에서 함수를 사용하지만 의사 코드는 다음과 같습니다.

    for (word : words) { 
        checkWord(download(url)) 
    } 
    

    하나의 솔루션은 매우 쉽습니다. 루프 앞에서 페이지를 다운로드하십시오. 다른 해결책은 다음과 같습니다.

메모리 누수 :

  • 간단한 : 당신은 또한 캐시의 종류의 문제를 해결할 수 있습니다. 가장 단순한 경우 결과를 (정적) 맵에 넣을 수 있습니다. 그러나 당신이 그것을 막지 않으면, 그 크기는 무한히 커지게 될 것입니다 -> 메모리 누출.
    가능한 해결책 : LRU 맵을 사용하십시오. 대부분의 성능이 저하되지는 않지만 메모리 누수는 사라집니다.
  • 더 까다 롭습니다. WeakHashMap을 사용하여 이전 캐시를 구현한다고 가정 해 봅시다. 여기에서 키는 URL (문자열이 아닌, 나중에 표시됨)이고, 값은 URL, 다운로드 한 페이지 및 기타 항목을 포함하는 클래스의 인스턴스입니다. 당신은 그것이 잘되어야한다고 가정할지 모르지만 실제로는 그렇지 않습니다 : 값 (약하게 참조되지 않음)이 키 (URL)에 대한 참조를 가지므로 키는 결코 정리할 자격이 없습니다 -> 훌륭한 메모리 누수 .
    해결책 : 값에서 URL을 제거하십시오.
  • 이전과 같지만 url은 interned 문자열입니다 ("동일한 문자열이 다시 발생하면 메모리를 절약하기 위해"). value는이를 참조하지 않습니다. 나는 그것을 시도하지는 않았지만, 그것은 또한 인턴 된 문자열이 GC화될 수 없기 때문에 누출을 유발할 것 같다.
    해결 방법 : 인턴은 아니므로 건너 뛰지 말아야하는 조언으로 이어집니다. premature optimization, as it is the root of all evil.

객체 생성 & 문자열 :

  • 은 (~ html 태그를 제거) 페이지 만의 텍스트를 표시하고 싶은 말은. 줄 단위로 수행하는 함수를 작성하고이를 증가하는 결과에 추가합니다. 처음에는 결과가 문자열이어야하므로 추가하는 데 많은 시간과 객체 할당이 필요합니다. 이 문제는 성능 관점에서 (추가가 왜 느린 지) 객체 생성 시점 (왜 우리가 많은 문자열, StringBuffer, 배열 등을 생성했는지)에서 감지 할 수 있습니다.
    해결 방법 : 결과에 StringBuilder를 사용하십시오.

동시성 :

  • 당신은 병렬로 다운로드/필터링을 수행하여 전체 물건을 빠르게합니다. 일부 스레드를 만들고이를 사용하여 코드를 실행하지만 캐시를 기반으로 큰 동기화 된 블록 내부의 모든 작업을 수행합니다. "동시성 문제에서 캐시를 보호"합니다. 캐시에있는 잠금을 획득하기 위해 다른 모든 스레드가 기다리고 있기 때문에 효과적으로 하나의 스레드 만 사용하는 것이 효과적입니다.
    해결책 : 캐시 작업 (예 : java.util.collections.synchronizedMap() 사용)에서만 동기화하십시오.

  • 모든 작은 코드를 동기화하십시오. 이렇게하면 성능이 저하되어 정상적인 병렬 실행을 방해 할 수 있습니다. 운이 좋으면/똑똑하다면 죽은 자물쇠도 나올 수 있습니다. 도덕적 : 동기화는 "상처 입지 않을 것"에 근거하여 일시적인 것이 아니라 잘 생각해야합니다.

보너스 운동 :

처음에 캐시를 작성하고 이후에 너무 많은 할당을하지 않는다, 그러나 아직도 어딘가에 작은 누수가. 보통이 패턴은 잡기가 쉽지 않습니다. 캐싱이 끝난 직후에 생성해야하는 프로파일 러의 "책갈피"또는 "워터 마크"기능을 사용할 수 있습니다.

1

어떤 언어 및 OS에서도 these reasons에 대해 매우 잘 작동하므로 this method을 무시하지 마십시오. 예는 here입니다. 또한 I/O 및 중요한 통화 깊이가있는 예제를 사용해보십시오. 만델 브로 (Mandelbrot)와 같은 작은 CPU 기반 프로그램을 사용하지 마십시오. 너무 크지 않은 C 예제를 Java로 재 코딩하면, 대부분의 요점을 설명해야한다.

보자 :

  • 해결 메모리 누수를.
    가비지 컬렉터의 핵심은 메모리 누수를 막는 것입니다. 그러나 여전히 너무 많은 메모리를 할당 할 수 있으며 일부 개체의 경우 "새로 만들기"에 많은 시간을 차지합니다.

  • 루프를 최적화하십시오.
    일반적으로 내부 루프가 거의 완료되지 않는 한 일반적으로 루프를 최적화 할 필요가 없습니다.

  • 개체 생성 및 관리를 최적화하십시오.
    기본 접근법은 다음과 같습니다. 데이터 구조를 인간적으로 가능한 단순하게 유지합니다. 특히 통보 스타일의 데이터 일관성을 유지하려는 시도는 피해야합니다. 왜냐하면 이러한 일이 사라져서 전화 트리가 엄청나게 부끄럽기 때문입니다. 이것은 큰 소프트웨어의 성능 문제의 주된 이유입니다.

  • 문자열 연산을 최적화하십시오.
    문자열 작성기를 사용하지만 실행 시간의 일정 비율을 사용하지 않는 코드는 사용하지 마십시오.

  • 동시성.
    동시성에는 두 가지 목적이 있습니다.
    1) 성능이지만이 은 여러 하드웨어가 동시에 크랭크를 수행 할 수있는 정도까지 작동합니다. 하드웨어가 없으면 도움이되지 않습니다. 아프다.
    2) 표현의 명확성. 예를 들어, UI 코드는 과중한 계산이나 네트워크 입출력에 대해 걱정할 필요가 없습니다.

어떤 경우에도 강조 할 수는 없지만 상당한 시간이 걸릴 것으로 판단되기 전에 최적화를 수행하지 마십시오.

+0

GC 언어를 사용하면 확실히 "실제"메모리 누수가 발생할 수 있습니다. –

+0

@Zwei : 네 말이 맞아. 이 방법은 100 % 문제를 해결하지 못합니다. 성능 문제가 아닌 메모리 증가 문제가있을 수 있습니다.그 경우, 잉여 오브젝트가 어디서 왔는지와 왜 풀어지지 않았는지 추적하는 툴이 필요합니다. –

+0

Mike, jdk 6을 사용하는 리눅스 머신에서'javap'은 '+'를 사용하여 연결된 문자열이 내부적으로 StringBuilder 클래스를 사용하도록 최적화되었음을 보여줍니다. 이것을 제안하기 전에 생성 된 바이트 코드를 살펴볼 가치가 있습니다. – questzen

0

우리 응용 프로그램을 프로파일 링하기 위해 JProfiler를 사용했습니다.하지만 많은 도움이되지 않았습니다. JHat를 사용했습니다. JHat를 사용하여 실시간으로 힙을 볼 수 없습니다. 힙 덤프를 가져 와서 분석해야합니다. . OQL(Object Query Language)을 사용하면 힙 누수를 찾을 수있는 좋은 방법입니다.