我正在尝试对一堆数据进行排序,使得输入到程序的数据大小可能大于JVM可用的内存,并且处理需要外部排序,这比Quicksort慢得多。
有没有办法在运行时获取JVM可用的内存,这样我就可以尽可能地使用就地排序,只在数据输入太大时切换到Mergesort?
答案 0 :(得分:8)
在java.lang.Runtime
类上查看这些方法:
示例强>
Runtime rt = Runtime.getRuntime();
System.err.println(String.format("Free: %d bytes, Total: %d bytes, Max: %d bytes",
rt.freeMemory(), rt.totalMemory(), rt.maxMemory()));
另请注意,如果内存总量耗尽,您始终可以使用-Xmx
JVM参数以较大的堆分配来启动JVM; e.g。
java -Xmx256M MyClass
答案 1 :(得分:1)
您可以使用Runtime类来获取可用的内存量。
Runtime r = Runtime.getRuntime();
System.out.println(r.totalMemory());
您可以从Runtime对象获得各种其他内存详细信息 - 请参阅Runtime class。
答案 2 :(得分:1)
理论上是的,使用Runtime.getRuntime().maxMemory()
。
在实践中,您需要解决一些问题:
您需要确定在给定的内存字节数中适合多少个应用程序对象。 AFAIK,在正在运行的应用程序中没有简单/有效的方法。
您不想尝试使用所有可用堆空间。如果你将百分比堆驻留率推得太高,你就有可能使GC非常低效。
maxMemory()
方法只能告诉您虚拟内存中堆的大小。物理尺寸也可以是一个因素(特别是如果物理尺寸<&lt;虚拟尺寸),并且没有可移植的方法来解决这个问题。
如果我试图实现这个应用程序,我想我可能只是让内存中的排序大小成为配置参数或命令行选项。
答案 3 :(得分:1)
正如其他人所建议的那样,使用Runtime的方法很好,只要你考虑一些事情:
1)freeMemory()是实际可用内存的下限,因为未引用且为GC准备好的内存被视为已使用。在调用之前运行System.gc()可能会返回更准确的结果。
2)totalMemory()可以更改 - 它仅指示当前的总堆大小,并且堆可以在运行时期间由JVM扩展/收缩,具体取决于其用法。您可以使用maxMemory()来获取实际最大值。