java system.freememory()_关于java:什么是Runtime.getRuntime()。totalMemory()和freeMemory()?...

我一直想知道Runtime.getRuntime()。totalMemory(),Runtime.getRuntime()。freeMemory()和Runtime.getRuntime()。maxMemory()的确切含义是什么。

我的理解是,Runtime.getRuntime().totalMemory()返回我的进程正在使用的总内存。 那是对的吗?

freeMemory()和maxMemory()怎么样?

名称和值令人困惑。如果您要寻找总的可用内存,则必须自行计算该值。这不是您从freeMemory();获得的。

请参阅以下指南:

指定的总内存,将等于配置的-Xmx值:

Runtime.getRuntime().maxMemory();

当前分配的可用内存是为新对象准备的当前分配空间。警告这不是可用的总可用内存:

Runtime.getRuntime().freeMemory();

总分配内存,是为java进程保留的总分配空间:

Runtime.getRuntime().totalMemory();

已用内存,必须计算:

usedMemory = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();

总可用内存,必须计算:

freeMemory = Runtime.getRuntime().maxMemory() - usedMemory;

图片可能有助于阐明:

59e438372c5b1077d49151f789d555d1.png

这与Debug.getMemoryInfo()不同吗?

注意:已用内存可能不再包含将被下一个GC清除的已引用对象。

@cheneym很棒的答案! 您启发了stackoverflow.com/a/42567450/253468

根据API

totalMemory()

返回Java虚拟机中的内存总量。此方法返回的值可能会随时间变化,具体取决于主机环境。

请注意,保存任何给定类型的对象所需的内存量可能取决于实现。

maxMemory()

返回Java虚拟机将尝试使用的最大内存量。如果没有固有限制,则将返回Long.MAX_VALUE值。

freeMemory()

返回Java虚拟机中的可用内存量。调用gc方法可能会增加freeMemory返回的值。

关于您的问题,maxMemory()返回-Xmx值。

您可能想知道为什么会有totalMemory()和maxMemory()。答案是JVM延迟分配内存。可以这样说启动Java进程:

java -Xms64m -Xmx1024m Foo

您的进程以64mb的内存开始,如果需要更多内存(最大1024m),它将分配内存。 totalMemory()对应于JVM for Foo当前可用的内存量。如果JVM需要更多内存,它将懒惰地分配它到最大内存。如果使用-Xms1024m -Xmx1024m运行,则从totalMemory()和maxMemory()获得的值将相等。

另外,如果要准确计算已用内存量,请执行以下计算:

final long usedMem = totalMemory() - freeMemory();

-Xmx值似乎直接影响初始的maxMemory()值,但是我已经看到报告的maxMemory()会在程序运行时增加少量,也许?1%。

与Debug.getNativeHeapFreeSize()有何不同?

@ H2ONaCl是的,它可能会略有变化,因为默认情况下启用了JVM UseAdaptiveSizePolicy。 顺便说一句:maxMemory() = Xmx-单个幸存空间的大小。 为什么? 因为同时只能使用一个幸存者空间。

为了更好地理解它,请运行以下程序(在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 cheneym's

* awesome interpretation

* 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.

*

 * Runtime's memory interpretation

*

* JVM memory management crash course:

* 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

*     What are Runtime.getRuntime().totalMemory() and freeMemory()?

* @see

*     Memory Management in the Sun Java HotSpot? Virtual Machine

* @see

*     Full VM options reference for Windows

* @see

*     Full VM options reference for Linux, Mac OS X and Solaris

* @see

*     Java HotSpot VM Options quick reference

*/

public class SystemMemory {

// can be white-box mocked for testing

private final Runtime runtime = Runtime.getRuntime();

/**

* Total allocated memory: space currently reserved for the JVM heap within the process.

*

* Caution: this is not the total memory, the JVM may grow the heap for new allocations.

*/

public long getAllocatedTotal() {

return runtime.totalMemory();

}

/**

* Current allocated free memory: space immediately ready for new objects.

*

* Caution: this is not the total free available memory,

* the JVM may grow the heap for new allocations.

*/

public long getAllocatedFree() {

return runtime.freeMemory();

}

/**

* Used memory:

* Java heap currently used by instantiated objects.

*

* Caution: 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();

}

/**

* Maximum allocation: the process' allocated memory will not grow any further.

*

* Caution: This may change over time, do not cache it!

* There are some JVMs / garbage collectors that can shrink the allocated process memory.

*

* Caution: If this is true, the JVM will likely run GC more often.

*/

public boolean isAtMaximumAllocation() {

return getAllocatedTotal() == getTotal();

// = return getUnallocated() == 0;

}

/**

* Unallocated memory: amount of space the process' heap can grow.

*/

public long getUnallocated() {

return getTotal() - getAllocatedTotal();

}

/**

* Total designated memory: this will equal the configured {@code -Xmx} value.

*

* Caution: You can never allocate more memory than this, unless you use native code.

*/

public long getTotal() {

return runtime.maxMemory();

}

/**

* Total free memory: 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();

}

/**

* Unbounded memory: 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.

*

* Caution: 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());

}

}

Runtime#totalMemory-到目前为止,JVM已分配的内存。这不一定是正在使用或最大的使用。

Runtime#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");

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值