001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.reef.util; 020 021import java.lang.management.ManagementFactory; 022import java.lang.management.MemoryPoolMXBean; 023import java.util.List; 024 025/** 026 * Utility class to report current and peak memory 027 * usage. Structured to be used while logging. Is 028 * useful for debugging memory issues 029 */ 030public final class MemoryUtils { 031 032 private static final int BYTES_IN_MEGABYTE = 1024 * 1024; 033 034 private MemoryUtils() { 035 } 036 037 public static String memPoolNames() { 038 final List<MemoryPoolMXBean> memoryPoolMXBeans = ManagementFactory.getMemoryPoolMXBeans(); 039 final StringBuilder output = new StringBuilder(); 040 for (final MemoryPoolMXBean bean : memoryPoolMXBeans) { 041 output.append(bean.getName()); 042 output.append(","); 043 } 044 output.deleteCharAt(output.length() - 1); 045 return output.toString(); 046 } 047 048 public static long currentEdenMemoryUsageMB() { 049 return currentMemoryUsage("eden"); 050 } 051 052 public static long currentOldMemoryUsageMB() { 053 return currentMemoryUsage("old"); 054 } 055 056 public static long currentPermMemoryUsageMB() { 057 return currentMemoryUsage("perm"); 058 } 059 060 private static long currentMemoryUsage(final String name) { 061 final List<MemoryPoolMXBean> memoryPoolMXBeans = ManagementFactory.getMemoryPoolMXBeans(); 062 for (final MemoryPoolMXBean bean : memoryPoolMXBeans) { 063 if (bean.getName().toLowerCase().indexOf(name) != -1) { 064 return bean.getUsage().getUsed() / BYTES_IN_MEGABYTE; 065 } 066 } 067 return 0; 068 } 069 070 public static long peakEdenMemoryUsageMB() { 071 return peakMemoryUsage("eden"); 072 } 073 074 public static long peakOldMemoryUsageMB() { 075 return peakMemoryUsage("old"); 076 } 077 078 public static long peakPermMemoryUsageMB() { 079 return peakMemoryUsage("perm"); 080 } 081 082 private static long peakMemoryUsage(final String name) { 083 final List<MemoryPoolMXBean> memoryPoolMXBeans = ManagementFactory.getMemoryPoolMXBeans(); 084 for (final MemoryPoolMXBean bean : memoryPoolMXBeans) { 085 if (bean.getName().toLowerCase().indexOf(name) != -1) { 086 return bean.getPeakUsage().getUsed() / BYTES_IN_MEGABYTE; 087 } 088 } 089 return 0; 090 } 091 092 public static void resetPeakUsage() { 093 final List<MemoryPoolMXBean> memoryPoolMXBeans = ManagementFactory.getMemoryPoolMXBeans(); 094 for (final MemoryPoolMXBean memoryPoolMXBean : memoryPoolMXBeans) { 095 memoryPoolMXBean.resetPeakUsage(); 096 } 097 } 098 099 /** 100 * Returns the total amount of physical memory on the current machine in megabytes. 101 * 102 * Some JVMs may not support the underlying API call. 103 * 104 * @return memory size in MB if the call succeeds; -1 otherwise 105 */ 106 public static int getTotalPhysicalMemorySizeInMB() { 107 108 int memorySizeInMB; 109 try { 110 long memorySizeInBytes = ((com.sun.management.OperatingSystemMXBean) ManagementFactory 111 .getOperatingSystemMXBean()).getTotalPhysicalMemorySize(); 112 113 memorySizeInMB = (int) (memorySizeInBytes / BYTES_IN_MEGABYTE); 114 } catch (Exception e) { 115 memorySizeInMB = -1; 116 } 117 118 return memorySizeInMB; 119 } 120 121 public static void main(final String[] args) { 122 System.out.println(memPoolNames()); 123 124 final byte[] b = new byte[1 << 24]; 125 System.out.println(currentEdenMemoryUsageMB() 126 + "," + currentOldMemoryUsageMB() 127 + "," + currentPermMemoryUsageMB()); 128 129 System.gc(); 130 System.out.println(currentEdenMemoryUsageMB() 131 + "," + currentOldMemoryUsageMB() 132 + "," + currentPermMemoryUsageMB()); 133 System.out.println(peakEdenMemoryUsageMB() 134 + "," + peakOldMemoryUsageMB() 135 + "," + peakPermMemoryUsageMB()); 136 resetPeakUsage(); 137 System.out.println(peakEdenMemoryUsageMB() 138 + "," + peakOldMemoryUsageMB() 139 + "," + peakPermMemoryUsageMB()); 140 } 141}