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.