>source

저는 때때로 몇 시간 동안 매우 높은 CPU 사용률 (거의 90 %)을 보여주는 Java 애플리케이션 (웹 기반)을 가지고 있습니다. 리눅스상단명령은 이것을 보여줍니다. 응용 프로그램을 다시 시작하면 문제가 사라집니다.

조사 대상 :

나는 스레드 덤프를 사용하여 스레드가 수행하는 작업을 찾습니다. 여러 스레드가 있습니다.'실행 가능'주, 일부 다른 주에서. 반복 된 스레드 덤프를 수행 할 때 항상 존재하는 일부 스레드를 볼 수 있습니다.'실행 가능'상태. 그래서 그들은 범인으로 보입니다.

하지만 어떤 스레드가 CPU를 잡아 먹고 있는지 또는 무한 루프에 빠졌는지 (이로 인해 높은 CPU 사용률을 유발 함) 확실히 알 수 없습니다.

문제를 일으키는 code가 아무것도 기록하지 않을 수 있으므로 로그가 반드시 도움이되는 것은 아닙니다.

어떻게 조사합니까?-애플리케이션의 어떤 부분 또는 어떤 스레드가 높은 CPU 사용률을 유발합니까? -다른 아이디어가 있습니까?

이미 프로파일 러를 사용해 보셨습니까?

andreapier2021-02-23 09:37:56

스레드 덤프는 code에서 이러한 Runnable 스레드가 스레드 덤프 중 어디에 있는지도 보여 주어야합니다. code를 살펴 봐야합니다. IIRC "실행 가능"스레드가 I /O를 기다리고 있고 CPU를 차지하지 않을 수 있지만 아직 이르고 여전히 커피를 간호하고 있습니다.

Charles Forsythe2021-02-23 09:37:56

andreapier>Prod 환경에서 프로파일 러를 사용할 수 없지만 프로파일 러가 CPU를 차지하는 스레드를 알려줄 수 있습니까?

Jasper2021-02-23 09:37:56

비슷한 code 줄에 많은 실행 파일이 있습니까? 그렇다면 공통 라인에 대한 스레드 덤프를 지나칠 수 있습니까?

John Vint2021-02-23 09:37:56
  • 답변 # 1

    프로파일 러가 설정에 적용되지 않는 경우의 단계에 따라 스레드를 식별 할 수 있습니다.

    기본적으로 다음 세 단계가 있습니다.

    1. 실행최고 -HCPU가 가장 높은 스레드의 PID를 가져옵니다.
    2. PID를 16 진수로 변환합니다.
    3. 스레드 덤프에서 일치하는 HEX PID를 가진 스레드를 찾습니다.

    Windows에서 동일한 것을 어떻게 얻을 수 있습니까?

    dom2021-02-23 09:37:56

    링크가 끊어졌습니다.

    Amir Fo2021-02-23 21:09:08

    web.archive.org/web/20190403090107/http://code.nomad-labs.com/…

    Dmytro Mitin2021-02-23 21:37:56

  • 답변 # 2

    Flame 그래프는 CPU 시간을 가장 많이 소비하는 실행 경로를 식별하는 데 도움이 될 수 있습니다. 내 탐험에서 생성하는 두 가지 방법이 있습니다.

    • 소개하여-XX : + PreserveFramePointer설명 된 JVM 옵션으로 여기
    • async-profiler를-XX : + UnlockDiagnosticVMOptions -XX : + DebugNonSafepoints설명한대로 여기

    매우 정확하지는 않지만 옵션을 제공하지 않고 async-profiler를 사용하면 프로세스에 대한 낮은 CPU 오버 헤드로 실행중인 Java 프로세스를 변경하지 않고도 활용할 수 있습니다. 그들의 위키이를 활용하는 방법에 대한 세부 정보를 제공합니다. 불꽃 그래프에 대한 자세한 내용은 여기

  • 답변 # 3

    당신은 질문에 "linux"를 할당하지 않았지만 "Linux top"을 언급했습니다. 따라서 이것은 도움이 될 수 있습니다.

    작은 Linux 도구 인 threadcpu를 사용하여 스레드를 사용하는 CPU를 가장 많이 식별합니다. 스레드 이름을 가져 오기 위해 jstack을 호출합니다. 그리고 파이프에서 "sort -n"을 사용하면 CPU 사용량에 따라 정렬 된 스레드 목록을 얻을 수 있습니다.

    자세한 내용은 여기에서 확인할 수 있습니다.

    더 자세한 정보가 필요한 경우 스레드 덤프를 생성하거나 스레드에서 strace를 실행하십시오.

  • 답변 # 4

    스레드 덤프에서 다음과 같은 줄 번호를 찾을 수 있습니다.

    현재 실행중인 메인 스레드의 경우 ...

    "main" #1 prio=5 os_prio=0 tid=0x0000000002120800 nid=0x13f4 runnable [0x0000000001d9f000]
       java.lang.Thread.State: **RUNNABLE**
        at java.io.FileOutputStream.writeBytes(Native Method)
        at java.io.FileOutputStream.write(FileOutputStream.java:313)
        at com.rana.samples.**HighCPUUtilization.main(HighCPUUtilization.java:17)**
    

    이 특정 스레드는 writeBytes OS 호출이 완료되기를 기다리고 있습니다. CPU주기를 거의 사용하지 않거나 전혀 사용하지 않습니다. 그러나 일반적인 접근 방식은 정확합니다. 스레드 덤프를 수행하고 계산을 수행하는 스레드를 찾습니다.

    rustyx2021-02-23 22:35:32
  • 답변 # 5

    가비지 수집 문제의 피해자 일 수 있습니다.

    애플리케이션에 메모리가 필요하고 가비지 수집기를 사용하도록 구성된 항목이 부족 해지면 많은 CPU주기를 소비하는 가비지 수집기가 자주 실행됩니다. 아무것도 수집 할 수 없으면 메모리가 부족하여 계속 실행됩니다. 애플리케이션을 재배포하면 메모리가 지워지고 가비지 수집이 필요한 것 이상으로 발생하지 않으므로 CPU 사용률은 다시 가득 찰 때까지 낮게 유지됩니다.

    애플리케이션에서 가능한 메모리 누수가 없는지, 메모리에 대해 제대로 구성되었는지 확인해야합니다 (-Xmx매개 변수, 참조 Java 옵션 -Xmx는 무엇을 의미합니까?)

    또한 웹 프레임 워크로 무엇을 사용하고 있습니까? JSF는 세션에 많이 의존하고 많은 메모리를 소비합니다.

    stop the world gc (본질적으로 당신이 말하는 것)는 멀티 스레드를 실행할 수 없습니다. 전체적으로 코어 중 하나를 사용한다는 것을 알 수 있습니다.

    drone.ah2021-02-23 09:37:56

    메모리 사용이 정상인 것 같습니다. Java Visual VM에서 GC (CPU) 활동이 상당히 낮은 것을 알 수 있습니다.

    Jasper2021-02-23 09:37:56

  • 답변 # 6

    이러한 최대 CPU 시간 동안 사용자로드는 어떻습니까? 이것이 웹 기반 애플리케이션이라고 말 했으므로 떠오르는 범인은 메모리 사용 문제입니다. 예를 들어 세션에 많은 항목을 저장하고 세션 수가 충분히 높아지면 앱 서버가 스 래싱을 시작합니다. 이것은 또한 사용하는 체계에 따라 GC가 문제를 악화시킬 수있는 경우이기도합니다. 앱 및 서버 구성에 대한 자세한 정보는 더 많은 디버깅 아이디어를 가리키는 데 도움이됩니다.

  • 답변 # 7

    첫 번째 접근 방식은 모든 참조를 찾고 다음 사항을 확인하는 것입니다.

    1. 수면은 올바른 일입니다. 가능하면 일종의 대기 메커니즘을 사용해야합니다.BlockingQueue도움이 될 것이다.

    2. 수면이 옳은 일인 경우 적절한 시간 동안 수면을 취하고 있습니까? 이것은 종종 대답하기 매우 어려운 질문입니다.

    멀티 스레드 디자인에서 가장 흔한 실수는 무언가가 일어나기를 기다릴 때해야 할 일은 그것을 확인하고 타이트한 루프에서 잠시 잠을자는 것 뿐이라고 믿는 것입니다. 이것은 효과적인 해결책이 아닙니다. 항상 시도해야합니다.기다림발생합니다.

    두 번째로 일반적인 문제는 자지 않고 반복하는 것입니다. 이것은 더 나쁘고 추적하기가 조금 덜 쉽습니다.

  • 이전 javascript : 태그에서 많은 작업을 수행하려면 어떻게해야합니까?
  • 다음 angular : 관찰 가능한 루프를 기다리는 방법