Runtime.getRuntime (). totalMemory () , Runtime.getRuntime (). freeMemory () 및 Runtime.getRuntime (). maxMemory () 의 정확한 의미가 무엇인지 궁금합니다 .
내 이해는 Runtime.getRuntime().totalMemory()
내 프로세스가 사용하는 총 메모리를 반환합니다. 그 맞습니까?
어떻 freeMemory()
와 maxMemory()
?
답변
API 에 따르면
totalMemory()
Java 가상 머신의 총 메모리 양을 리턴합니다. 이 방법으로 반환되는 값은 호스트 환경에 따라 시간이 지남에 따라 달라질 수 있습니다. 주어진 유형의 객체를 보유하는 데 필요한 메모리 양은 구현에 따라 다를 수 있습니다.
maxMemory()
Java 가상 머신이 사용하려고하는 최대 메모리 양을 리턴합니다. 고유 제한이 없으면 Long.MAX_VALUE 값이 반환됩니다.
freeMemory()
JVM (Java Virtual Machine)에서 사용 가능한 메모리 양을 리턴합니다. gc 메소드를 호출하면 freeMemory에서 리턴 한 값이 증가 할 수 있습니다.
질문과 관련 maxMemory()
하여 -Xmx
값을 반환합니다 .
totalMemory () 및 maxMemory () 가 왜 있는지 궁금 할 것 입니다. 대답은 JVM이 느리게 메모리를 할당한다는 것입니다. 다음과 같이 Java 프로세스를 시작한다고 가정하십시오.
java -Xms64m -Xmx1024m Foo
프로세스는 64MB의 메모리로 시작하며 더 많은 양이 필요할 때 (최대 1024m) 메모리를 할당합니다. JVM for Foo에서 현재 사용 가능한 totalMemory()
메모리 양에 해당합니다 . JVM에 더 많은 메모리가 필요한 경우 최대 메모리 까지 느리게 할당합니다 . 당신이 실행하는 경우 , 당신은에서 얻을 값 과 동일 할 것이다.-Xms1024m -Xmx1024m
totalMemory()
maxMemory()
또한 사용 된 메모리 의 양을 정확하게 계산 하려면 다음 계산을 수행하십시오.
final long usedMem = totalMemory() - freeMemory();
답변
이름과 값이 혼동됩니다. 사용 가능한 총 메모리 를 찾고 있다면 이 값을 스스로 계산해야합니다. 그것은 당신이 얻는 것이 아닙니다freeMemory();
.
다음 안내서를 참조하십시오.
지정된 총 메모리 . 구성된 -Xmx 값과 같습니다.
Runtime.getRuntime (). maxMemory ();
현재 할당 된 여유 메모리 는 새 객체를 위해 준비된 현재 할당 된 공간 입니다. 주의 이것은 사용 가능한 총 여유 메모리 가 아닙니다 .
Runtime.getRuntime (). freeMemory ();
총 할당 메모리 는 Java 프로세스를 위해 예약 된 총 할당 공간입니다 .
Runtime.getRuntime (). totalMemory ();
사용한 메모리 는 다음과 같이 계산되어야합니다.
usedMemory = Runtime.getRuntime (). totalMemory ()-Runtime.getRuntime (). freeMemory ();
사용 가능한 총 메모리 는 다음과 같이 계산해야합니다.
freeMemory = Runtime.getRuntime (). maxMemory ()-usedMemory;
사진은 다음을 명확히하는 데 도움이 될 수 있습니다.
답변
더 잘 이해하려면 다음 프로그램을 실행하십시오 (jdk1.7.x).
$ java -Xms1025k -Xmx1025k -XshowSettings:vm MemoryTest
이것은 jvm 을 인쇄합니다 옵션과 사용 , 무료 , 총 및 최대 JVM에서 사용 가능한 메모리를.
public class MemoryTest {
public static void main(String args[]) {
System.out.println("Used Memory : " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) + " bytes");
System.out.println("Free Memory : " + Runtime.getRuntime().freeMemory() + " bytes");
System.out.println("Total Memory : " + Runtime.getRuntime().totalMemory() + " bytes");
System.out.println("Max Memory : " + Runtime.getRuntime().maxMemory() + " bytes");
}
}
답변
다른 모든 답변의 체계화 된 버전 (작성 당시) :
import java.io.*;
/**
* This class is based on <a href="http://stackoverflow.com/users/2478930/cheneym">cheneym</a>'s
* <a href="http://stackoverflow.com/a/18375641/253468">awesome interpretation</a>
* of the Java {@link Runtime}'s memory query methods, which reflects intuitive thinking.
* Also includes comments and observations from others on the same question, and my own experience.
* <p>
* <img src="https://i.stack.imgur.com/GjuwM.png" alt="Runtime's memory interpretation">
* <p>
* <b>JVM memory management crash course</b>:
* Java virtual machine process' heap size is bounded by the maximum memory allowed.
* The startup and maximum size can be configured by JVM arguments.
* JVMs don't allocate the maximum memory on startup as the program running may never require that.
* This is to be a good player and not waste system resources unnecessarily.
* Instead they allocate some memory and then grow when new allocations require it.
* The garbage collector will be run at times to clean up unused objects to prevent this growing.
* Many parameters of this management such as when to grow/shrink or which GC to use
* can be tuned via advanced configuration parameters on JVM startup.
*
* @see <a href="http://stackoverflow.com/a/42567450/253468">
* What are Runtime.getRuntime().totalMemory() and freeMemory()?</a>
* @see <a href="http://www.oracle.com/technetwork/java/javase/memorymanagement-whitepaper-150215.pdf">
* Memory Management in the Sun Java HotSpot™ Virtual Machine</a>
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/java.html">
* Full VM options reference for Windows</a>
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html">
* Full VM options reference for Linux, Mac OS X and Solaris</a>
* @see <a href="http://www.oracle.com/technetwork/articles/java/vmoptions-jsp-140102.html">
* Java HotSpot VM Options quick reference</a>
*/
public class SystemMemory {
// can be white-box mocked for testing
private final Runtime runtime = Runtime.getRuntime();
/**
* <b>Total allocated memory</b>: space currently reserved for the JVM heap within the process.
* <p>
* <i>Caution</i>: this is not the total memory, the JVM may grow the heap for new allocations.
*/
public long getAllocatedTotal() {
return runtime.totalMemory();
}
/**
* <b>Current allocated free memory</b>: space immediately ready for new objects.
* <p>
* <i>Caution</i>: this is not the total free available memory,
* the JVM may grow the heap for new allocations.
*/
public long getAllocatedFree() {
return runtime.freeMemory();
}
/**
* <b>Used memory</b>:
* Java heap currently used by instantiated objects.
* <p>
* <i>Caution</i>: May include no longer referenced objects, soft references, etc.
* that will be swept away by the next garbage collection.
*/
public long getUsed() {
return getAllocatedTotal() - getAllocatedFree();
}
/**
* <b>Maximum allocation</b>: the process' allocated memory will not grow any further.
* <p>
* <i>Caution</i>: This may change over time, do not cache it!
* There are some JVMs / garbage collectors that can shrink the allocated process memory.
* <p>
* <i>Caution</i>: If this is true, the JVM will likely run GC more often.
*/
public boolean isAtMaximumAllocation() {
return getAllocatedTotal() == getTotal();
// = return getUnallocated() == 0;
}
/**
* <b>Unallocated memory</b>: amount of space the process' heap can grow.
*/
public long getUnallocated() {
return getTotal() - getAllocatedTotal();
}
/**
* <b>Total designated memory</b>: this will equal the configured {@code -Xmx} value.
* <p>
* <i>Caution</i>: You can never allocate more memory than this, unless you use native code.
*/
public long getTotal() {
return runtime.maxMemory();
}
/**
* <b>Total free memory</b>: memory available for new Objects,
* even at the cost of growing the allocated memory of the process.
*/
public long getFree() {
return getTotal() - getUsed();
// = return getAllocatedFree() + getUnallocated();
}
/**
* <b>Unbounded memory</b>: there is no inherent limit on free memory.
*/
public boolean isBounded() {
return getTotal() != Long.MAX_VALUE;
}
/**
* Dump of the current state for debugging or understanding the memory divisions.
* <p>
* <i>Caution</i>: Numbers may not match up exactly as state may change during the call.
*/
public String getCurrentStats() {
StringWriter backing = new StringWriter();
PrintWriter out = new PrintWriter(backing, false);
out.printf("Total: allocated %,d (%.1f%%) out of possible %,d; %s, %s %,d%n",
getAllocatedTotal(),
(float)getAllocatedTotal() / (float)getTotal() * 100,
getTotal(),
isBounded()? "bounded" : "unbounded",
isAtMaximumAllocation()? "maxed out" : "can grow",
getUnallocated()
);
out.printf("Used: %,d; %.1f%% of total (%,d); %.1f%% of allocated (%,d)%n",
getUsed(),
(float)getUsed() / (float)getTotal() * 100,
getTotal(),
(float)getUsed() / (float)getAllocatedTotal() * 100,
getAllocatedTotal()
);
out.printf("Free: %,d (%.1f%%) out of %,d total; %,d (%.1f%%) out of %,d allocated%n",
getFree(),
(float)getFree() / (float)getTotal() * 100,
getTotal(),
getAllocatedFree(),
(float)getAllocatedFree() / (float)getAllocatedTotal() * 100,
getAllocatedTotal()
);
out.flush();
return backing.toString();
}
public static void main(String... args) {
SystemMemory memory = new SystemMemory();
System.out.println(memory.getCurrentStats());
}
}
답변
런타임 #totalMemory -JVM이 지금까지 할당 한 메모리 이것이 반드시 사용중인 것이거나 최대 값 인 것은 아닙니다.
런타임 #maxMemory -JVM이 사용하도록 구성된 최대 메모리 양. 프로세스가이 양에 도달하면 JVM은 더 많이 할당하지 않고 대신 GC를 훨씬 더 많이 할당합니다.
Runtime # freeMemory- 이것이 최대 또는 사용되지 않은 총계의 부분에서 측정되는지 확실하지 않습니다. 나는 그것이 사용되지 않은 총 부분의 측정이라고 생각합니다.
답변
가비지 콜렉션 메커니즘으로 JVM 힙 크기를 늘리거나 줄일 수 있습니다. 그러나 최대 메모리 크기 (Runtime.maxMemory)를 초과하여 할당 할 수 없습니다. 이것이 최대 메모리의 의미입니다. 총 메모리는 할당 된 힙 크기를 의미합니다. 여유 메모리는 총 메모리에서 사용 가능한 크기를 의미합니다.
예) java -Xms20M -Xmn10M -Xmx50M ~~~. 이것은 jvm이 start (ms)에 힙 20M을 할당해야 함을 의미합니다. 이 경우 총 메모리는 20M입니다. 사용 가능한 메모리는 20M 사용 크기입니다. 더 많은 힙이 필요한 경우 JVM은 더 많이 할당하지만 50M (mx)을 초과 할 수 없습니다. 최대 메모리의 경우 총 메모리는 50M이고 사용 가능한 크기는 50M 사용 크기입니다. 최소 크기 (mn)의 경우 힙을 많이 사용하지 않으면 jvm은 힙 크기를 10M으로 축소 할 수 있습니다.
이 메커니즘은 메모리 효율성을위한 것입니다. 작은 Java 프로그램이 거대한 고정 크기 힙 메모리에서 실행되면 많은 메모리가 낭비 될 수 있습니다.
답변
사용자는 결과에서 볼 수있는 MB 형식 의 분할과, 1024 X 1024 같은지 1 MB .
int dataSize = 1024 * 1024;
System.out.println("Used Memory : " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/dataSize + " MB");
System.out.println("Free Memory : " + Runtime.getRuntime().freeMemory()/dataSize + " MB");
System.out.println("Total Memory : " + Runtime.getRuntime().totalMemory()/dataSize + " MB");
System.out.println("Max Memory : " + Runtime.getRuntime().maxMemory()/dataSize + " MB");