Java에서 CPU 및 메모리 사용량을 어떻게 확인합니까?


답변:


73

JVM에서 특별히 메모리를 찾고 있다면 :

Runtime runtime = Runtime.getRuntime();

NumberFormat format = NumberFormat.getInstance();

StringBuilder sb = new StringBuilder();
long maxMemory = runtime.maxMemory();
long allocatedMemory = runtime.totalMemory();
long freeMemory = runtime.freeMemory();

sb.append("free memory: " + format.format(freeMemory / 1024) + "<br/>");
sb.append("allocated memory: " + format.format(allocatedMemory / 1024) + "<br/>");
sb.append("max memory: " + format.format(maxMemory / 1024) + "<br/>");
sb.append("total free memory: " + format.format((freeMemory + (maxMemory - allocatedMemory)) / 1024) + "<br/>");

그러나 이것은 추정치로만 취해야합니다 ...


따라서 Eclipse에서 실행중인 경우 Eclipse 설정에 따라 달라집니다.
— Coffee '

4
이것은 실제 사용 된 메모리가 아닙니다. 이것은 자바가 할당 한 힙을 의미하는 '할당 된 메모리'입니다. 따라서 -Xms90g가 있고 앱이 매우 가볍다면 여전히 90g보다 큰 할당 된 메모리를 얻게됩니다. . 아래에서 삭제 된 "알 수 없음 (yahoo)"의 답변을 참조하십시오 (첫눈에 다를 수 있음)
— 0fnt

궁금한 점이 있는데, 왜 이것들은 추정치 여야합니까?
— ComputerScientist

@ComputerScientist 무료는 실제로 무료이기 때문에 (GC 이후) GC를 기다리는 개체를 표시하지 않습니다. 보다 정확한 정보를 얻으려면이 답변 전에 2 개의 가비지 수집을 실행하십시오. GC를 사용하거나 사용하지 않고 시도하면 GC 이후 값이 매우 일관 적이지만 preGC는 일반적으로 최소 두 배입니다.
— Bill K

@sbeliakov JavaSysmon ( github.com/jezhumble/javasysmon )을 사용할 수 있지만 새 질문을 여는 것이 좋습니다. 그러면 대답하겠습니다. GitHub의 라이브러리에는 버그가 있고 32 비트를 64 비트로 인식하지만 다른 jar [ github.com/goxr3plus/XR3Player/blob/master/resources/libs/… ]를 혼합하는 방법을 찾았습니다 .
— GOXR3PLUS

20
package mkd.Utils;

import java.io.File;
import java.text.NumberFormat;

public class systemInfo {

    private Runtime runtime = Runtime.getRuntime();

    public String Info() {
        StringBuilder sb = new StringBuilder();
        sb.append(this.OsInfo());
        sb.append(this.MemInfo());
        sb.append(this.DiskInfo());
        return sb.toString();
    }

    public String OSname() {
        return System.getProperty("os.name");
    }

    public String OSversion() {
        return System.getProperty("os.version");
    }

    public String OsArch() {
        return System.getProperty("os.arch");
    }

    public long totalMem() {
        return Runtime.getRuntime().totalMemory();
    }

    public long usedMem() {
        return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
    }

    public String MemInfo() {
        NumberFormat format = NumberFormat.getInstance();
        StringBuilder sb = new StringBuilder();
        long maxMemory = runtime.maxMemory();
        long allocatedMemory = runtime.totalMemory();
        long freeMemory = runtime.freeMemory();
        sb.append("Free memory: ");
        sb.append(format.format(freeMemory / 1024));
        sb.append("<br/>");
        sb.append("Allocated memory: ");
        sb.append(format.format(allocatedMemory / 1024));
        sb.append("<br/>");
        sb.append("Max memory: ");
        sb.append(format.format(maxMemory / 1024));
        sb.append("<br/>");
        sb.append("Total free memory: ");
        sb.append(format.format((freeMemory + (maxMemory - allocatedMemory)) / 1024));
        sb.append("<br/>");
        return sb.toString();

    }

    public String OsInfo() {
        StringBuilder sb = new StringBuilder();
        sb.append("OS: ");
        sb.append(this.OSname());
        sb.append("<br/>");
        sb.append("Version: ");
        sb.append(this.OSversion());
        sb.append("<br/>");
        sb.append(": ");
        sb.append(this.OsArch());
        sb.append("<br/>");
        sb.append("Available processors (cores): ");
        sb.append(runtime.availableProcessors());
        sb.append("<br/>");
        return sb.toString();
    }

    public String DiskInfo() {
        /* Get a list of all filesystem roots on this system */
        File[] roots = File.listRoots();
        StringBuilder sb = new StringBuilder();

        /* For each filesystem root, print some info */
        for (File root : roots) {
            sb.append("File system root: ");
            sb.append(root.getAbsolutePath());
            sb.append("<br/>");
            sb.append("Total space (bytes): ");
            sb.append(root.getTotalSpace());
            sb.append("<br/>");
            sb.append("Free space (bytes): ");
            sb.append(root.getFreeSpace());
            sb.append("<br/>");
            sb.append("Usable space (bytes): ");
            sb.append(root.getUsableSpace());
            sb.append("<br/>");
        }
        return sb.toString();
    }
}

주제가 시작된 것은 OS에서 사용 가능한 메모리 양에 대한 질문이라는 것을 이해했습니다. freeMemory여기는 매우 다른 JVM에서 사용 가능한 메모리 양을 반환합니다.
— Tagar

SystemInfo 클래스가 Capital로 시작하지 않고 Info (), OSname (), MemInfo () 메서드가 수행하는 것이 이상하지 않습니까?
— Drswaki69

18

Sun JVM을 사용하고 있고 애플리케이션의 내부 메모리 사용량 (앱이 사용중인 할당 된 메모리 중 얼마나 많은 양)에 관심이 있다면 JVM 내장 가비지 수집 로깅을 사용하는 것을 선호합니다. 시작 명령에 -verbose : gc를 추가하기 만하면됩니다.

Sun 문서에서 :

명령 줄 인수 -verbose : gc는 모든 컬렉션에서 정보를 인쇄합니다. -verbose : gc 출력의 형식은 J2SE 플랫폼의 릴리스간에 변경 될 수 있습니다. 예를 들어, 다음은 대규모 서버 애플리케이션의 출력입니다.

[GC 325407K->83000K(776768K), 0.2300771 secs]
[GC 325816K->83372K(776768K), 0.2454258 secs]
[Full GC 267628K->83769K(776768K), 1.8479984 secs]

여기서 우리는 두 개의 마이너 컬렉션과 하나의 메이저 컬렉션을 볼 수 있습니다. 화살표 앞뒤의 숫자

325407K->83000K (in the first line)

각각 가비지 수집 전후의 라이브 개체의 결합 된 크기를 나타냅니다. 마이너 컬렉션 후 카운트에는 반드시 살아있을 필요는 없지만 회수 할 수없는 개체가 포함됩니다. 개체가 직접 살아 있기 때문이거나 보유 세대 내에 있거나 참조되기 때문입니다. 괄호 안의 숫자

(776768K) (in the first line)

영구 세대의 공간을 계산하지 않고 사용 가능한 총 공간으로, 총 힙에서 생존자 공간 중 하나를 뺀 값입니다. 마이너 컬렉션은 약 1/4 초가 걸렸습니다.

0.2300771 secs (in the first line)

자세한 내용은 http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html을 참조하십시오.


17

에서 여기

    OperatingSystemMXBean operatingSystemMXBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
    RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
    int availableProcessors = operatingSystemMXBean.getAvailableProcessors();
    long prevUpTime = runtimeMXBean.getUptime();
    long prevProcessCpuTime = operatingSystemMXBean.getProcessCpuTime();
    double cpuUsage;
    try
    {
        Thread.sleep(500);
    }
    catch (Exception ignored) { }

    operatingSystemMXBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
    long upTime = runtimeMXBean.getUptime();
    long processCpuTime = operatingSystemMXBean.getProcessCpuTime();
    long elapsedCpu = processCpuTime - prevProcessCpuTime;
    long elapsedTime = upTime - prevUpTime;

    cpuUsage = Math.min(99F, elapsedCpu / (elapsedTime * 10000F * availableProcessors));
    System.out.println("Java CPU: " + cpuUsage);

1
그리고 기억에 대해?
— Daniel De León 2013 년

2
List <MemoryPoolMXBean> memoryPools = new ArrayList <MemoryPoolMXBean> (ManagementFactory.getMemoryPoolMXBeans ()); long usedHeapMemoryAfterLastGC = 0; for (MemoryPoolMXBean memoryPool : memoryPools) {if (memoryPool.getType (). equals (MemoryType.HEAP)) {MemoryUsage poolCollectionMemoryUsage = memoryPool.getCollectionUsage (); usedHeapMemoryAfterLastGC + = poolCollectionMemoryUsage.getUsed (); }}
— danieln

1
CPU 사용량 검색을 보여주는 유일한 답변에 감사드립니다.
— Matthieu

1
이것을하는 것과 단순히하는 것의 차이점은 무엇입니까 operatingSystemMXBean.getProcessCpuLoad();? Oracle 설명서에 따르면이 메서드는 "Java Virtual Machine 프로세스에 대한"최근 CPU 사용량 "을 반환합니다."를 반환합니다. 그러나 나는 당신의 방법과이 방법 사이에 상대적으로 큰 차이를 봅니다.
— Ishnark

1
@RobHall 두 가지 OperatingSystemMXBean클래스가 있습니다. 하나는 java.lang. 그러나 .NET에서이 버전을 확장하는 다른 버전도 있습니다 com.sun.management. 그것이 제가 언급 한 방법입니다OperatingSystemMXBean
— Ishnark

9

JMX, 제공된 MXBean (ThreadMXBean 등)은 메모리 및 CPU 사용량을 제공합니다.

OperatingSystemMXBean operatingSystemMXBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
operatingSystemMXBean.getSystemCpuLoad();

8

메모리 사용량의 경우 다음이 작동합니다.

long total = Runtime.getRuntime().totalMemory();
long used  = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();

CPU 사용량의 경우이를 측정하기 위해 외부 애플리케이션을 사용해야합니다.


6

Java 1.5부터 JDK에는 새로운 도구가 함께 제공됩니다. JConsole 은 1.5 이상의 JVM의 CPU 및 메모리 사용량을 보여줄 수 있습니다. 이러한 매개 변수의 차트를 수행하고 CSV로 내보내고로드 된 클래스 수, 인스턴스 수, 교착 상태, 스레드 등을 표시 할 수 있습니다.


4

여기에 많은 답변에 게시 된 runtime / totalMemory 솔루션을 사용하는 경우 (많은 작업을 수행했습니다) 상당히 정확하고 일관된 결과를 원하면 먼저 두 개의 가비지 수집을 강제하십시오.

효율성을 위해 Java는 일반적으로 GC를 강제 실행하기 전에 가비지가 모든 메모리를 채울 수 있도록 허용하며 일반적으로 완전한 GC가 아니므로 runtime.freeMemory ()에 대한 결과는 항상 "실제"메모리 양과 0 사이의 어딘가에 있습니다. .

첫 번째 GC는 모든 것을 얻는 것이 아니라 대부분을 얻습니다.

상승세는 freeMemory () 호출 만하면 절대적으로 쓸모없고 광범위하게 변하는 숫자를 얻을 수 있다는 것입니다. 그러나 2 gc를 먼저 수행하면 매우 신뢰할 수있는 게이지입니다. 또한 루틴을 훨씬 느리게 만듭니다 (아마도 초).


3

Java의 런타임 객체는 JVM의 메모리 사용량을보고 할 수 있습니다. CPU 소비의 경우 Unix의 top 또는 Windows Process Manager와 같은 외부 유틸리티를 사용해야합니다.


2

JConsole 은 실행중인 Java 애플리케이션을 모니터링하는 쉬운 방법이거나 프로파일 러를 사용하여 애플리케이션에 대한 자세한 정보를 얻을 수 있습니다. 저는이를 위해 NetBeans Profiler 를 사용하는 것을 좋아 합니다.


2

다음은 현재 메모리 사용량을 메가 바이트 단위로 계산하는 간단한 코드입니다.

double currentMemory = ( (double)((double)(Runtime.getRuntime().totalMemory()/1024)/1024))- ((double)((double)(Runtime.getRuntime().freeMemory()/1024)/1024));

2

또한 CPU로드를 추적하기 위해 다음 방법을 추가합니다.

import java.lang.management.ManagementFactory;
import com.sun.management.OperatingSystemMXBean;

double getCpuLoad() {
    OperatingSystemMXBean osBean =
        (com.sun.management.OperatingSystemMXBean) ManagementFactory.
        getPlatformMXBeans(OperatingSystemMXBean.class);
    return osBean.getProcessCpuLoad();
}

여기에서 더 많은 것을 읽을 수 있습니다



1

Tomcat을 사용하는 경우 내부 및 외부 메모리 소비는 물론 다른 영역의 호스트를 모니터링 할 수있는 Psi Probe를 확인하십시오 .


당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.