| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more contributor license |
| * agreements. See the NOTICE file distributed with this work for additional information regarding |
| * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance with the License. You may obtain a |
| * copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software distributed under the License |
| * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
| * or implied. See the License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| package org.apache.geode.internal; |
| |
| |
| import org.apache.commons.lang3.JavaVersion; |
| |
| import org.apache.geode.annotations.Immutable; |
| import org.apache.geode.internal.lang.SystemUtils; |
| import org.apache.geode.unsafe.internal.sun.misc.Unsafe; |
| |
| /** |
| * The class provides info about some JVM characteristics |
| */ |
| public class JvmSizeUtils { |
| |
| private static final boolean is64Bit; |
| private static final int referenceSize; |
| private static final int objectHeaderSize; |
| |
| @Immutable |
| private static final Unsafe unsafe; |
| static { |
| Unsafe tmp = null; |
| try { |
| tmp = new Unsafe(); |
| } catch (RuntimeException ignore) { |
| } catch (Error ignore) { |
| } |
| unsafe = tmp; |
| } |
| |
| static { |
| int sunbits = Integer.getInteger("sun.arch.data.model", 0).intValue(); // also used by JRockit |
| if (sunbits == 64) { |
| is64Bit = true; |
| } else if (sunbits == 32) { |
| is64Bit = false; |
| } else { |
| int ibmbits = Integer.getInteger("com.ibm.vm.bitmode", 0).intValue(); |
| if (ibmbits == 64) { |
| is64Bit = true; |
| } else if (ibmbits == 32) { |
| is64Bit = false; |
| } else { |
| if (unsafe != null) { |
| is64Bit = unsafe.getAddressSize() == 8; |
| } else { |
| is64Bit = false; |
| } |
| } |
| } |
| if (!is64Bit) { |
| referenceSize = 4; |
| objectHeaderSize = 8; |
| } else { |
| int scaleIndex = 0; |
| int tmpReferenceSize = 0; |
| int tmpObjectHeaderSize = 0; |
| if (SystemUtils.isAzulJVM()) { |
| tmpObjectHeaderSize = 8; |
| tmpReferenceSize = 8; |
| } else { |
| if (unsafe != null) { |
| // Use unsafe to figure out the size of an object reference since we might |
| // be using compressed oops. |
| // Note: as of java 8 compressed oops do not imply a compressed object header. |
| // The object header is determined by UseCompressedClassPointers. |
| // UseCompressedClassPointers requires UseCompressedOops |
| // but UseCompressedOops does not require UseCompressedClassPointers. |
| // But it seems unlikely that someone would compress their oops |
| // not their class pointers. |
| scaleIndex = unsafe.arrayScaleIndex(Object[].class); |
| if (scaleIndex == 4) { |
| // compressed oops |
| tmpReferenceSize = 4; |
| tmpObjectHeaderSize = 12; |
| } else if (scaleIndex == 8) { |
| tmpReferenceSize = 8; |
| tmpObjectHeaderSize = 16; |
| } else { |
| System.out.println("Unexpected arrayScaleIndex " + scaleIndex |
| + ". Using max heap size to estimate reference size."); |
| scaleIndex = 0; |
| } |
| } |
| if (scaleIndex == 0) { |
| // If our heap is > 32G (64G on java 8) then assume large oops. Otherwise assume |
| // compressed oops. |
| long SMALL_OOP_BOUNDARY = 32L; |
| if (org.apache.commons.lang3.SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_1_8)) { |
| SMALL_OOP_BOUNDARY = 64L; |
| } |
| if (Runtime.getRuntime().maxMemory() > (SMALL_OOP_BOUNDARY * 1024 * 1024 * 1024)) { |
| tmpReferenceSize = 8; |
| tmpObjectHeaderSize = 16; |
| } else { |
| tmpReferenceSize = 4; |
| tmpObjectHeaderSize = 12; |
| } |
| } |
| } |
| referenceSize = tmpReferenceSize; |
| objectHeaderSize = tmpObjectHeaderSize; |
| } |
| } |
| |
| /** |
| * @return true if this process is 64bit |
| * @throws RuntimeException if sun.arch.data.model doesn't fit expectations |
| */ |
| public static boolean is64Bit() { |
| return is64Bit; |
| } |
| |
| public static int getReferenceSize() { |
| return referenceSize; |
| } |
| |
| public static int getObjectHeaderSize() { |
| return objectHeaderSize; |
| } |
| } |