[FLINK-2235] fix calculation of free memory for local execution

The Java runtime may return Long.MAX_VALUE for a call to the maxMemory()
method of the Runtime class. In these cases, we can get hold of the
physical memory size of the operating system by using a proprietary
Oracle JDK method. Otherwise, we fail with an explanatory exception.

The Oracle JVM defines the max memory to be 1/4 of the physical memory
if the user has more than 192 Megabytes which is assumed here.

This closes #859


Project: http://git-wip-us.apache.org/repos/asf/flink/repo
Commit: http://git-wip-us.apache.org/repos/asf/flink/commit/910e8c43
Tree: http://git-wip-us.apache.org/repos/asf/flink/tree/910e8c43
Diff: http://git-wip-us.apache.org/repos/asf/flink/diff/910e8c43

Branch: refs/heads/master
Commit: 910e8c438477f27c6d20392d00dd0cfbe8496c8b
Parents: 2ccb5fd
Author: Maximilian Michels <[email protected]>
Authored: Mon Jun 22 17:47:11 2015 +0200
Committer: Stephan Ewen <[email protected]>
Committed: Mon Jul 13 17:54:31 2015 +0200

----------------------------------------------------------------------
 .../runtime/util/EnvironmentInformation.java     | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flink/blob/910e8c43/flink-runtime/src/main/java/org/apache/flink/runtime/util/EnvironmentInformation.java
----------------------------------------------------------------------
diff --git 
a/flink-runtime/src/main/java/org/apache/flink/runtime/util/EnvironmentInformation.java
 
b/flink-runtime/src/main/java/org/apache/flink/runtime/util/EnvironmentInformation.java
index 630e227..736b2b5 100644
--- 
a/flink-runtime/src/main/java/org/apache/flink/runtime/util/EnvironmentInformation.java
+++ 
b/flink-runtime/src/main/java/org/apache/flink/runtime/util/EnvironmentInformation.java
@@ -20,6 +20,7 @@ package org.apache.flink.runtime.util;
 
 import java.io.InputStream;
 import java.lang.management.ManagementFactory;
+import java.lang.management.OperatingSystemMXBean;
 import java.lang.management.RuntimeMXBean;
 import java.lang.reflect.Method;
 import java.util.List;
@@ -138,7 +139,23 @@ public class EnvironmentInformation {
         */
        public static long getSizeOfFreeHeapMemory() {
                Runtime r = Runtime.getRuntime();
-               return r.maxMemory() - r.totalMemory() + r.freeMemory();
+               long maxMemory = r.maxMemory();
+
+               if (maxMemory == Long.MAX_VALUE) {
+                       // amount of free memory unknown
+                       try {
+                               // workaround for Oracle JDK
+                               OperatingSystemMXBean operatingSystemMXBean = 
ManagementFactory.getOperatingSystemMXBean();
+                               Class<?> clazz = 
Class.forName("com.sun.management.OperatingSystemMXBean");
+                               Method method = 
clazz.getMethod("getTotalPhysicalMemorySize");
+                               maxMemory = (Long) 
method.invoke(operatingSystemMXBean) / 4;
+                       } catch (Throwable e) {
+                               throw new RuntimeException("Could not determine 
the amount of free memory.\n" +
+                                               "Please set the maximum memory 
for the JVM, e.g. -Xmx512M for 512 megabytes.");
+                       }
+               }
+
+               return maxMemory - r.totalMemory() + r.freeMemory();
        }
 
        /**

Reply via email to