IGNITE-5248 - Detect a 32-bit JVM using too large init page size. Closes #1976
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/c5a04da7 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/c5a04da7 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/c5a04da7 Branch: refs/heads/ignite-5075 Commit: c5a04da7103701d4ee95910d90ba786a6ea5750b Parents: 2110994 Author: Wuwei Lin <[email protected]> Authored: Tue May 23 11:35:24 2017 +0300 Committer: Alexey Goncharuk <[email protected]> Committed: Tue May 23 11:35:24 2017 +0300 ---------------------------------------------------------------------- .../mem/unsafe/UnsafeMemoryProvider.java | 18 +++++++++++++- .../IgniteCacheDatabaseSharedManager.java | 25 ++++++++++++++++++-- .../ignite/internal/util/IgniteUtils.java | 17 +++++++++++++ 3 files changed, 57 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/c5a04da7/modules/core/src/main/java/org/apache/ignite/internal/mem/unsafe/UnsafeMemoryProvider.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/mem/unsafe/UnsafeMemoryProvider.java b/modules/core/src/main/java/org/apache/ignite/internal/mem/unsafe/UnsafeMemoryProvider.java index ef101d0..bf6e807 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/mem/unsafe/UnsafeMemoryProvider.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/mem/unsafe/UnsafeMemoryProvider.java @@ -20,6 +20,7 @@ package org.apache.ignite.internal.mem.unsafe; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import org.apache.ignite.IgniteException; import org.apache.ignite.IgniteLogger; import org.apache.ignite.internal.mem.DirectMemoryProvider; import org.apache.ignite.internal.mem.DirectMemoryRegion; @@ -73,7 +74,22 @@ public class UnsafeMemoryProvider implements DirectMemoryProvider { long chunkSize = sizes[regions.size()]; - long ptr = GridUnsafe.allocateMemory(chunkSize); + long ptr; + + try { + ptr = GridUnsafe.allocateMemory(chunkSize); + } + catch (IllegalArgumentException e) { + String msg = "Failed to allocate next memory chunk: " + U.readableSize(chunkSize, true) + + ". Check if chunkSize is too large and 32-bit JVM is used."; + + if (regions.size() == 0) + throw new IgniteException(msg, e); + + U.error(log, msg); + + return null; + } if (ptr <= 0) { U.error(log, "Failed to allocate next memory chunk: " + U.readableSize(chunkSize, true)); http://git-wip-us.apache.org/repos/asf/ignite/blob/c5a04da7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java index 7151b2f..fbb3b0f 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java @@ -72,6 +72,9 @@ public class IgniteCacheDatabaseSharedManager extends GridCacheSharedManagerAdap /** Minimum size of memory chunk */ private static final long MIN_PAGE_MEMORY_SIZE = 10 * 1024 * 1024; + /** Maximum initial size on 32-bit JVM */ + private static final long MAX_PAGE_MEMORY_INIT_SIZE_32_BIT = 2L * 1024 * 1024 * 1024; + /** */ protected Map<String, MemoryPolicy> memPlcMap; @@ -354,8 +357,14 @@ public class IgniteCacheDatabaseSharedManager extends GridCacheSharedManagerAdap private void checkSystemMemoryPolicySizeConfiguration(long sysCacheInitSize, long sysCacheMaxSize) throws IgniteCheckedException { if (sysCacheInitSize < MIN_PAGE_MEMORY_SIZE) throw new IgniteCheckedException("Initial size for system cache must have size more than 10MB (use " + - "MemoryConfiguration.systemCacheInitialSize property to set correct size in bytes); " + - "size: " + U.readableSize(sysCacheInitSize, true) + "MemoryConfiguration.systemCacheInitialSize property to set correct size in bytes) " + + "[size=" + U.readableSize(sysCacheInitSize, true) + ']' + ); + + if (U.jvm32Bit() && sysCacheInitSize > MAX_PAGE_MEMORY_INIT_SIZE_32_BIT) + throw new IgniteCheckedException("Initial size for system cache exceeds 2GB on 32-bit JVM (use " + + "MemoryPolicyConfiguration.systemCacheInitialSize property to set correct size in bytes " + + "or use 64-bit JVM) [size=" + U.readableSize(sysCacheInitSize, true) + ']' ); if (sysCacheMaxSize < sysCacheInitSize) @@ -388,6 +397,12 @@ public class IgniteCacheDatabaseSharedManager extends GridCacheSharedManagerAdap if (dfltPlcSize < MIN_PAGE_MEMORY_SIZE) throw new IgniteCheckedException("User-defined default MemoryPolicy size is less than 1MB. " + "Use MemoryConfiguration.defaultMemoryPolicySize property to set correct size."); + + if (U.jvm32Bit() && dfltPlcSize > MAX_PAGE_MEMORY_INIT_SIZE_32_BIT) + throw new IgniteCheckedException("User-defined default MemoryPolicy size exceeds 2GB on 32-bit JVM " + + "(use MemoryConfiguration.defaultMemoryPolicySize property to set correct size in bytes " + + "or use 64-bit JVM) [size=" + U.readableSize(dfltPlcSize, true) + ']' + ); } if (!DFLT_MEM_PLC_DEFAULT_NAME.equals(dfltPlcName)) { @@ -416,6 +431,12 @@ public class IgniteCacheDatabaseSharedManager extends GridCacheSharedManagerAdap "initialSize [name=" + plcCfg.getName() + ", initSize=" + U.readableSize(plcCfg.getInitialSize(), true) + ", maxSize=" + U.readableSize(plcCfg.getMaxSize(), true) + ']'); + + if (U.jvm32Bit() && plcCfg.getInitialSize() > MAX_PAGE_MEMORY_INIT_SIZE_32_BIT) + throw new IgniteCheckedException("MemoryPolicy initialSize exceeds 2GB on 32-bit JVM (use " + + "MemoryPolicyConfiguration.initialSize property to set correct size in bytes or use 64-bit JVM) " + + "[name=" + plcCfg.getName() + + ", size=" + U.readableSize(plcCfg.getInitialSize(), true) + "]"); } /** http://git-wip-us.apache.org/repos/asf/ignite/blob/c5a04da7/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java index 0668708..4e9d0c7 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java @@ -416,6 +416,9 @@ public abstract class IgniteUtils { /** Name of the JVM implementation. */ private static String jvmImplName; + /** Will be set to {@code true} if detected a 32-bit JVM. */ + private static boolean jvm32Bit; + /** JMX domain as 'xxx.apache.ignite'. */ public static final String JMX_DOMAIN = IgniteUtils.class.getName().substring(0, IgniteUtils.class.getName(). indexOf('.', IgniteUtils.class.getName().indexOf('.') + 1)); @@ -607,6 +610,9 @@ public abstract class IgniteUtils { String jvmImplVendor = System.getProperty("java.vm.vendor"); String jvmImplName = System.getProperty("java.vm.name"); + // Best effort to detect a 32-bit JVM. + String jvmArchDataModel = System.getProperty("sun.arch.data.model"); + String jdkStr = javaRtName + ' ' + javaRtVer + ' ' + jvmImplVendor + ' ' + jvmImplName + ' ' + jvmImplVer; @@ -628,6 +634,8 @@ public abstract class IgniteUtils { IgniteUtils.javaRtName = javaRtName; IgniteUtils.javaRtVer = javaRtVer; + jvm32Bit = "32".equals(jvmArchDataModel); + primitiveMap.put("byte", byte.class); primitiveMap.put("short", short.class); primitiveMap.put("int", int.class); @@ -6509,6 +6517,15 @@ public abstract class IgniteUtils { } /** + * Does a best effort to detect if we a running on a 32-bit JVM. + * + * @return {@code true} if detected that we are running on a 32-bit JVM. + */ + public static boolean jvm32Bit() { + return jvm32Bit; + } + + /** * Compare java implementation version * * @param v1 - java implementation version
