001/*
002 * This file is part of McIDAS-V
003 *
004 * Copyright 2007-2024
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 https://www.gnu.org/licenses/.
027 */
028
029package edu.wisc.ssec.mcidasv.util;
030
031import java.lang.management.ManagementFactory;
032import java.lang.management.OperatingSystemMXBean;
033
034import javax.management.MBeanServer;
035import javax.management.ObjectName;
036
037/**
038 * Wrapper for OperatingSystemMXBean.
039 *
040 * <p>Note: this class is likely to be used in contexts where we don't
041 * have logging set up, so {@link System#err} and {@link System#out} are used.
042 */
043public class GetMem {
044
045    /**
046     * Query an {@link OperatingSystemMXBean} attribute and return the result.
047     * 
048     * @param <T> Type of the expected return value and {@code defaultValue}.
049     * @param attrName Name of the {@code OperatingSystemMXBean} attribute to 
050     *                 query. Cannot be {@code null} or empty.
051     * @param defaultValue Value returned if {@code attrName} could not be 
052     *                     queried.
053     * 
054     * @return Either the value corresponding to {@code attrName} or 
055     *         {@code defaultValue}.
056     */
057    private static <T> T queryPlatformBean(final String attrName,
058                                           final T defaultValue)
059    {
060        assert attrName != null : "Cannot query a null attribute name";
061        assert !attrName.isEmpty() : "Cannot query an empty attribute name";
062        T result = defaultValue;
063        try {
064            final ObjectName objName =
065                new ObjectName("java.lang", "type", "OperatingSystem");
066            final MBeanServer beanServer =
067                ManagementFactory.getPlatformMBeanServer();
068            final Object attr = beanServer.getAttribute(objName, attrName);
069            if (attr != null) {
070                // don't suppress warnings because we cannot guarantee that 
071                // this cast is correct.
072                result = (T)attr;
073            }
074        } catch (Exception e) {
075            System.err.println("Couldn't query attribute: " + attrName);
076        }
077        return result;
078    }
079
080    /**
081     * Get total system memory and print it out--accounts for 32bit JRE 
082     * limitation of 1.5GB.
083     * 
084     * @return {@code String} representation of the total amount of system 
085     * memory.
086     */
087    public static String getMemory() {
088        GetMem nonStaticInstance = new GetMem();
089        Object totalMemoryObject = queryPlatformBean("TotalPhysicalMemorySize", Long.MIN_VALUE);
090        long totalMemory = ((Number)totalMemoryObject).longValue();
091        boolean is64 = System.getProperty("os.arch").contains("64");
092        int megabytes = Math.round(totalMemory / 1024 / 1024);
093        if (!is64 && (megabytes > 1536)) {
094            megabytes = 1536;
095        }
096        return String.valueOf(megabytes);
097    }
098
099    /**
100     * The main. Get total system memory and print it out.
101     * 
102     * @param args Ignored.
103     */
104    public static void main(String[] args) {
105        try {
106            System.out.println(getMemory());
107        } catch (Exception e) {
108            System.err.println("Error getting total physical memory size");
109            System.out.println("0");
110        }
111    }
112}