有类似的问题,但他们似乎避免回答这个特定的问题。如何通过Java的Runtime api获取我的Java程序使用的内存?
answer 指出我可以这样做:
System.out.println("KB: " + (double) (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1024);
但是,无论我运行哪个程序,这总是返回相同的数字。例如,下面我有一个程序,在这个程序中,无论我在映射中输入多少数字,内存使用都保持不变。
package memoryTest;
import java.util.HashMap;
import java.util.Map;
public class MemoryTest {
static Map<Integer, NewObject> map = new HashMap<Integer, NewObject>();
public static void main(String[] args){
System.out.println("KB: " + (double) (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1024);
fillMemory(25);
System.out.println("KB: " + (double) (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1024);
}
static int j=0;
public static void fillMemory(int i){
for(int k=0; k< 2000; k++)
map.put(j++, new NewObject());
}
public static class NewObject{
long i = 0L;
long j = 0L;
long k = 0L;
}
}
通过cambecc的main方法,输出为:
3085,总计: 128516096,免费: 127173744,差异: 671120
173579,总计: 128516096,免费: 110033976,差异: 671128
335207,总计: 128516096,免费: 92417792,差异: 637544
672788,总计: 224198656,免费: 159302960,差异: 1221520
1171480,总计: 224198656,免费: 106939136,差异: 1221544
1489771,总计: 368377856,免费: 227374816,差异: 1212984
1998743,总计: 368377856,免费: 182494408,差异: 1212984
发布于 2013-06-29 13:02:34
你这样做是正确的。获取内存使用量的方法与您所描述的完全相同:
Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()
但是,您的程序总是返回相同的内存使用率,这是因为您没有创建足够的对象来克服freeMemory
方法的精度限制。虽然它有字节分辨率,但不能保证freeMemory
需要多精确。javadoc也是这么说的:
是当前可供将来分配的对象使用的内存总量的近似值,以字节为单位。
尝试执行以下操作,这将创建两百万个NewObject
实例,并在每次freeMemory
的结果发生变化时打印输出:
public static void main(String[] args) {
Runtime rt = Runtime.getRuntime();
long prevTotal = 0;
long prevFree = rt.freeMemory();
for (int i = 0; i < 2_000_000; i++) {
long total = rt.totalMemory();
long free = rt.freeMemory();
if (total != prevTotal || free != prevFree) {
System.out.println(
String.format("#%s, Total: %s, Free: %s, Diff: %s",
i,
total,
free,
prevFree - free));
prevTotal = total;
prevFree = free;
}
map.put(i, new NewObject());
}
}
在我的机器上,我看到如下输出
#0, Total: 513998848, Free: 508635256, Diff: 0
#21437, Total: 513998848, Free: 505953496, Diff: 2681760
#48905, Total: 513998848, Free: 503271728, Diff: 2681768
#73394, Total: 513998848, Free: 500589960, Diff: 2681768
#103841, Total: 513998848, Free: 497908192, Diff: 2681768
...
注意到报告的空闲内存在21,437个对象实例化之前是如何变化的吗?这些数字表明,我正在使用的JVM (Java7 Win 64位)的freeMemory
的精度刚刚超过2.5MB (尽管如果你运行这个实验,你会看到这个数字有所不同)。
-编辑--
此代码与上面的代码相同,但会打印更多有关内存使用的详细信息。希望它能更清楚地了解JVM的内存使用行为。我们在循环中不断地分配新的对象。在每次迭代期间,如果totalMemory
或freeMemory
与上一次迭代相同,则不会打印任何内容。但是如果其中任何一个发生了变化,我们就会报告当前的内存使用情况。∆
值表示当前使用情况与上一次内存报告之间的差异。
public static void main(String[] args) {
Runtime rt = Runtime.getRuntime();
long prevTotal = 0;
long prevFree = rt.freeMemory();
for (int i = 0; i < 2_000_000; i++) {
long total = rt.totalMemory();
long free = rt.freeMemory();
if (total != prevTotal || free != prevFree) {
long used = total - free;
long prevUsed = (prevTotal - prevFree);
System.out.println(
"#" + i +
", Total: " + total +
", Used: " + used +
", ∆Used: " + (used - prevUsed) +
", Free: " + free +
", ∆Free: " + (free - prevFree));
prevTotal = total;
prevFree = free;
}
map.put(i, new NewObject());
}
}
在我的笔记本上,我看到以下输出。注意:根据操作系统、硬件、JVM实现等的不同,您的结果会有所不同:
#0, Total: 83427328, Used: 1741048, ∆Used: 83427328, Free: 81686280, ∆Free: 0
#3228, Total: 83427328, Used: 1741080, ∆Used: 32, Free: 81686248, ∆Free: -32
#3229, Total: 83427328, Used: 2176280, ∆Used: 435200, Free: 81251048, ∆Free: -435200
#7777, Total: 83427328, Used: 2176312, ∆Used: 32, Free: 81251016, ∆Free: -32
#7778, Total: 83427328, Used: 2611536, ∆Used: 435224, Free: 80815792, ∆Free: -435224
...
#415056, Total: 83427328, Used: 41517072, ∆Used: 407920, Free: 41910256, ∆Free: -407920
#419680, Total: 145358848, Used: 39477560, ∆Used: -2039512, Free: 105881288, ∆Free: 63971032
#419681, Total: 145358848, Used: 40283832, ∆Used: 806272, Free: 105075016, ∆Free: -806272
...
从这些数据中可以观察到一些情况:
正如预期的那样,
发布于 2018-03-26 17:47:34
我有以下方法
public static long getMaxMemory() {
return Runtime.getRuntime().maxMemory();
}
public static long getUsedMemory() {
return getMaxMemory() - getFreeMemory();
}
public static long getTotalMemory() {
return Runtime.getRuntime().totalMemory();
}
public static long getFreeMemory() {
return Runtime.getRuntime().freeMemory();
}
它以字节为单位返回(已使用的)内存。
如果你想重新计算到MiB,我有:
private static final long MEGABYTE_FACTOR = 1024L * 1024L;
private static final DecimalFormat ROUNDED_DOUBLE_DECIMALFORMAT;
private static final String MIB = "MiB";
static {
DecimalFormatSymbols otherSymbols = new DecimalFormatSymbols(Locale.ENGLISH);
otherSymbols.setDecimalSeparator('.');
otherSymbols.setGroupingSeparator(',');
ROUNDED_DOUBLE_DECIMALFORMAT = new DecimalFormat("####0.00", otherSymbols);
ROUNDED_DOUBLE_DECIMALFORMAT.setGroupingUsed(false);
}
public static String getTotalMemoryInMiB() {
double totalMiB = bytesToMiB(getTotalMemory());
return String.format("%s %s", ROUNDED_DOUBLE_DECIMALFORMAT.format(totalMiB), MIB);
}
public static String getFreeMemoryInMiB() {
double freeMiB = bytesToMiB(getFreeMemory());
return String.format("%s %s", ROUNDED_DOUBLE_DECIMALFORMAT.format(freeMiB), MIB);
}
public static String getUsedMemoryInMiB() {
double usedMiB = bytesToMiB(getUsedMemory());
return String.format("%s %s", ROUNDED_DOUBLE_DECIMALFORMAT.format(usedMiB), MIB);
}
public static String getMaxMemoryInMiB() {
double maxMiB = bytesToMiB(getMaxMemory());
return String.format("%s %s", ROUNDED_DOUBLE_DECIMALFORMAT.format(maxMiB), MIB);
}
public static double getPercentageUsed() {
return ((double) getUsedMemory() / getMaxMemory()) * 100;
}
public static String getPercentageUsedFormatted() {
double usedPercentage = getPercentageUsed();
return ROUNDED_DOUBLE_DECIMALFORMAT.format(usedPercentage) + "%";
}
发布于 2020-06-13 22:05:07
public static void memoryStats() {
int mb = 1024 * 1024;
// get Runtime instance
Runtime instance = Runtime.getRuntime();
System.out.println("***** Heap utilization statistics [MB] *****\n");
// available memory
System.out.println("Total Memory: " + instance.totalMemory() / mb);
// free memory
System.out.println("Free Memory: " + instance.freeMemory() / mb);
// used memory
System.out.println("Used Memory: "
+ (instance.totalMemory() - instance.freeMemory()) / mb);
// Maximum available memory
System.out.println("Max Memory: " + instance.maxMemory() / mb);
}
参考:Here
https://stackoverflow.com/questions/17374743
复制相似问题