001    /*
002     * This file is part of McIDAS-V
003     *
004     * Copyright 2007-2013
005     * Space Science and Engineering Center (SSEC)
006     * University of Wisconsin - Madison
007     * 1225 W. Dayton Street, Madison, WI 53706, USA
008     * https://www.ssec.wisc.edu/mcidas
009     * 
010     * All Rights Reserved
011     * 
012     * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
013     * some McIDAS-V source code is based on IDV and VisAD source code.  
014     * 
015     * McIDAS-V is free software; you can redistribute it and/or modify
016     * it under the terms of the GNU Lesser Public License as published by
017     * the Free Software Foundation; either version 3 of the License, or
018     * (at your option) any later version.
019     * 
020     * McIDAS-V is distributed in the hope that it will be useful,
021     * but WITHOUT ANY WARRANTY; without even the implied warranty of
022     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
023     * GNU Lesser Public License for more details.
024     * 
025     * You should have received a copy of the GNU Lesser Public License
026     * along with this program.  If not, see http://www.gnu.org/licenses.
027     */
028    
029    package edu.wisc.ssec.mcidasv.util;
030    
031    import java.lang.management.ManagementFactory;
032    import java.lang.management.OperatingSystemMXBean;
033    import java.lang.reflect.Method;
034    
035    /**
036     * Wrapper for OperatingSystemMXBean
037     */
038    public class GetMem {
039    
040        /**
041         * Call a method belonging to {@link OperatingSystemMXBean} and return 
042         * the result. 
043         * 
044         * @param <T> Type of the expected return and {@code defaultValue}.
045         * @param methodName Name of the {@code OperatingSystemMXBean} method to call. Cannot be {@code null} or empty.
046         * @param defaultValue Value to return if the call to {@code methodName} fails.
047         * 
048         * @return Either the value returned by the {@code methodName} call, or {@code defaultValue}.
049         */
050        private <T> T callMXBeanMethod(final String methodName, final T defaultValue) {
051            assert methodName != null : "Cannot invoke a null method name";
052            assert methodName.length() > 0: "Cannot invoke an empty method name";
053            OperatingSystemMXBean osBean = 
054                ManagementFactory.getOperatingSystemMXBean();
055            T result = defaultValue;
056            try {
057                Method m = osBean.getClass().getMethod(methodName);
058                m.setAccessible(true);
059                // don't suppress warnings because we cannot guarantee that this
060                // cast is correct.
061                result = (T)m.invoke(osBean);
062            } catch (Exception e) {
063                System.err.println("Error invoking OperatingSystemMXBean method: " + methodName);
064                // do nothing for right now
065            }
066            return result;
067        }
068    
069        /**
070         * Get total system memory and print it out--accounts for 32bit JRE 
071         * limitation of 1.5GB.
072         * 
073         * @return {@code String} representation of the total amount of system 
074         * memory. 
075         * 
076         * @throws Exception
077         */
078        public static String getMemory() throws Exception {
079            GetMem nonStaticInstance = new GetMem();
080            Object totalMemoryObject = nonStaticInstance.callMXBeanMethod("getTotalPhysicalMemorySize", 0);
081            long totalMemory = ((Number)totalMemoryObject).longValue();
082            boolean is64 = (System.getProperty("os.arch").indexOf("64") >= 0);
083            int megabytes = (int)(Math.round(totalMemory/1024/1024));
084            if (!is64 && megabytes > 1536) {
085                megabytes = 1536;
086            }
087            return String.valueOf(megabytes);
088        }
089    
090        /**
091         * The main. Get total system memory and print it out.
092         * 
093         * @param args Ignored.
094         */
095        public static void main(String[] args) {
096            try {
097                System.out.println(getMemory());
098            } catch (Exception e) {
099                System.err.println("Error getting total physical memory size");
100                System.out.println("0");
101            }
102        }
103    }