Java는 사용 가능한 메모리를 얻습니다.
런타임에 JVM에서 사용 가능한 남은 메모리를 얻는 좋은 방법이 있습니까? 이것의 사용 사례는 OutOfMemory 오류로 갑자기 죽지 않고 "너무 많은 사람들이 이것을 사용하고 나중에 다시 시도하십시오"라는 멋진 오류 메시지와 함께 새로운 연결을 거부하여 메모리 제한에 가까워지면 정상적으로 실패하는 웹 서비스를 갖는 것입니다. .
이것은 미리 각 개체의 비용을 계산 / 추정하는 것과는 관련이 없습니다. 원칙적으로 나는 그 추정치를 기반으로 내 객체가 얼마나 많은 메모리를 차지하고 새로운 연결을 거부하는지 추정 할 수 있지만, 그것은 일종의 해키 / 깨지기 쉬운 것처럼 보입니다.
William Brendel의이 샘플은 유용 할 수 있습니다.
편집 : 원래이 샘플을 제공했습니다 (다른 주제에 대한 William Brendel의 답변 링크). 해당 주제의 작성자 (Steve M)는 다중 플랫폼 Java 애플리케이션을 만들고 싶었습니다. 특히 사용자는 실행중인 시스템의 리소스 (디스크 공간, CPU 및 메모리 사용량)를 평가할 수단을 찾으려고했습니다.
이것은 해당 주제에 제공된 답변의 인라인 사본입니다. 그러나이 주제에 대해 내 대답이 수락 된 것으로 표시 되었음에도 불구하고 이상적인 해결책이 아니라는 지적이있었습니다.
public class Main {
public static void main(String[] args) {
/* Total number of processors or cores available to the JVM */
System.out.println("Available processors (cores): " +
Runtime.getRuntime().availableProcessors());
/* Total amount of free memory available to the JVM */
System.out.println("Free memory (bytes): " +
Runtime.getRuntime().freeMemory());
/* This will return Long.MAX_VALUE if there is no preset limit */
long maxMemory = Runtime.getRuntime().maxMemory();
/* Maximum amount of memory the JVM will attempt to use */
System.out.println("Maximum memory (bytes): " +
(maxMemory == Long.MAX_VALUE ? "no limit" : maxMemory));
/* Total memory currently in use by the JVM */
System.out.println("Total memory (bytes): " +
Runtime.getRuntime().totalMemory());
/* Get a list of all filesystem roots on this system */
File[] roots = File.listRoots();
/* For each filesystem root, print some info */
for (File root : roots) {
System.out.println("File system root: " + root.getAbsolutePath());
System.out.println("Total space (bytes): " + root.getTotalSpace());
System.out.println("Free space (bytes): " + root.getFreeSpace());
System.out.println("Usable space (bytes): " + root.getUsableSpace());
}
}
}
사용자 Christian Fries Runtime.getRuntime().freeMemory()는 메모리 부족 오류가 발생할 때까지 할당 될 수있는 메모리 양 을 제공 한다고 가정하는 것은 잘못된 것이라고 지적 합니다.
로부터 문서 의 서명 수익률은 Runtime.getRuntime().freeMemory()같은 것입니다 :
반환 값 : 향후 할당 된 개체에 대해 현재 사용할 수있는 총 메모리 양에 대한 근사값 (바이트 단위).
그러나 사용자 Christian Fries는이 기능이 잘못 해석 될 수 있다고 주장합니다. 그는 메모리 부족 오류 (사용 가능한 메모리)가 발생할 때까지 할당 될 수있는 대략적인 메모리 양은 다음과 같이 제공 될 수 있다고 주장합니다.
long presumableFreeMemory = Runtime.getRuntime().maxMemory() - allocatedMemory;
에 allocatedMemory의해 주어진 :
long allocatedMemory =
(Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory());
여기서 핵심은 여유 메모리 개념 사이의 불일치입니다. 한 가지는 운영 체제가 Java Virtual Machine을 제공하는 메모리입니다. 다른 하나는 Java Virtual Machine 자체에서 실제로 사용되는 메모리 블록 청크를 구성하는 총 바이트 양입니다.
Java 응용 프로그램에 제공된 메모리가 Java Virtual Machine에 의해 블록으로 관리된다는 점을 고려할 때 Java Virtual Machine에 사용 가능한 메모리 양이 Java 응용 프로그램에 사용 가능한 메모리와 정확히 일치하지 않을 수 있습니다.
특히 Christian Fries는 -mx또는 -Xmx플래그를 사용하여 Java Virtual Machine에 사용할 수있는 최대 메모리 양을 설정합니다. 그는 다음과 같은 기능 차이에 주목합니다.
/* Returns the maximum amount of memory available to
the Java Virtual Machine set by the '-mx' or '-Xmx' flags. */
Runtime.getRuntime().maxMemory();
/* Returns the total memory allocated from the system
(which can at most reach the maximum memory value
returned by the previous function). */
Runtime.getRuntime().totalMemory();
/* Returns the free memory *within* the total memory
returned by the previous function. */
Runtime.getRuntime().freeMemory();
Christian은 Runtime.getRuntime().freeMemory()사실상 추정 가능한 여유 기억이라고 할 수있는 것을 반환 한다고 말함으로써 대답을 마무리 합니다. 향후 메모리 할당이 해당 함수에 의해 반환 된 값을 초과하지 않더라도 Java Virtual Machine이 호스트 시스템에서 할당 한 실제 메모리 청크를 아직 수신하지 않은 java.lang.OutOfMemoryError경우 여전히 a 가 생성 될 수 있습니다.
In the end, the proper method to use will have a varying degree of dependence on the specifics of your application.
I provide another link which may be useful. It is a question made by user Richard Dormand and answered by stones333 about determining the default Java heap size used.
Note: All the answers so far, even the accepted one, seem to answer the question by saying that Runtime.getRuntime().freeMemory() gives you the amount of memory which may be allocated until an out-of-memory error occurs. However: this is wrong.
The approximate amount of memory which may be allocated until an out-of-memory error occurs, i.e., the free memory is likely
long presumableFreeMemory = Runtime.getRuntime().maxMemory() - allocatedMemory;
where
long allocatedMemory = (Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory());
Explanation: If you launch the JVM via an -mx parameter (or -Xmx) you specify the maximum amount available to the JVM. Runtime.getRuntime().maxMemory() will give you this amount. From this amount of system memory the JVM will allocate memory in chunks, say for example blocks of 64 mb. At start, the JVM will only allocate such a chunk from the system and not the full amount. Runtime.getRuntime().totalMemory() gives the total memory allocated from the system, while Runtime.getRuntime().freeMemory() gives you the free memory within the total memory allocated.
Hence:
long definitelyFreeMemory = Runtime.getRuntime().freeMemory();
is the free memory already reserved by the JVM, but it is likely just a small amount. And you will likely get presumableFreeMemory. Of course, you may get an out-of-memory exception even if you tried to allocate an amount smaller than presumableFreeMemory. This may happen if the JVM does not get the next memory chunk from the system. However, on most systems this will never happen and the system will rather start swapping - a situation you like to avoid. W.r.t. to the original question: if -mx is set to a reasonable value, then presumableFreeMemory is a good indicator for the free memory.
In addition to using the Runtime methods, you can get some additional memory info using
MemoryMXBean memBean = ManagementFactory.getMemoryMXBean();
MemoryUsage heap = memBean.getHeapMemoryUsage();
MemoryUsage nonheap = memBean.getNonHeapMemoryUsage();
Each MemoryUsage provides init, used, committed and max values. This might be useful if create a memory monitor thread which polls memory and logs it, providing you with a history of memory usage over time. Sometimes it's helpful to see the memory usage over time leading up to the errors.
If you really want to take this to an extreme, create a heap dump thread. Monitor your memory usage over time and when it exceeds certain thresholds do the following (this works on JBoss 5.0 - your mileage may vary):
// init code
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
HotSpotDiagnosticMXBean diagBean = ManagementFactory.newPlatformMXBeanProxy(server, "com.sun.management:type=HotSpotDiagnostic", HotSpotDiagnosticMXBean.class);
// loop code
// add some code to figure if we have passed some threshold, then
File heapFile = new File(outputDir, "heap-" + curThreshold + ".hprof");
log.info("Dumping heap file " + heapFile.getAbsolutePath());
diagBean.dumpHeap(heapFile.getAbsolutePath(), true);
Later you can review these heap dump files with the eclipse memory analyzer or similar tools to check for memory leaks etc.
In addition to the other answer, I would like to note that doing that is not necessarily a good idea, since you might have a cache in your app that uses SoftReferences.
Such a cache would release memory as soon as the JVM reaches its memory limits. Allocating memory, even if there's not enough free memory, would first cause memory to be released by the soft references, and make it available for the allocation.
To get the OS-wide available memory, add OSHI by using the following maven dependency:
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
<version>LATEST</version>
</dependency>
Then in Java, use the following code:
SystemInfo si = new SystemInfo();
HardwareAbstractionLayer hal = si.getHardware();
long availableMemory = hal.getMemory().getAvailable();
You can always call Runtime.getRuntime().freeMemory().
The other half of the problem, getting the cost of objects, seems more problematic to me.
I think a better solution would be figuring out how to cluster and scale your web services so they can gracefully accept 150% of rated load without denying new connections. Sounds like a sizing exercise would get you a better solution than a code hack.
long freeMemory = Runtime.getRuntime().freeMemory();
Runtime.getRuntime().freeMemory() is a way to get free memory for JVM at that moment while runtime. Is it good way (or) not it depends completely on your application.
참고URL : https://stackoverflow.com/questions/12807797/java-get-available-memory
'program story' 카테고리의 다른 글
| “패키지 'android'의 'showAsAction'속성에 대한 리소스 식별자가 없습니다.” (0) | 2020.11.23 |
|---|---|
| 나뭇 가지 템플릿에서 돈 서식 지정 (0) | 2020.11.23 |
| 파이썬에서 ** kwargs를 사용하는 이유는 무엇입니까? (0) | 2020.11.23 |
| .NET에서 프로그래밍 방식으로 Windows 서비스를 다시 시작하는 방법 (0) | 2020.11.23 |
| 새로 설치 한 후 Postgresql에 어떻게 로그인하고 인증합니까? (0) | 2020.11.23 |