Last active
November 16, 2016 15:42
-
-
Save kares/9a3dd0e29be1d9bb42e7d0d758fa1079 to your computer and use it in GitHub Desktop.
periodically print JVM memory usage and load
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| require 'logger' | |
| Class.new do | |
| LOGGER = Logger.new(STDOUT) | |
| # Logger.new File.open('jmx.log', File::WRONLY | File::APPEND) | |
| def initialize; @done = nil end | |
| def start | |
| thread = Thread.new { log_usage while ! @done } | |
| Kernel.at_exit { @done = true; thread.join(1) } | |
| end | |
| def log_usage | |
| log_system_load_with_process | |
| log_heap_mem_usage | |
| log_perm_gen_usage | |
| sleep calc_sleep_time | |
| rescue => e | |
| LOGGER.warn "#{e.inspect}\n #{(e.backtrace || []).join("\n ")}"; @done = :error | |
| end | |
| def log_memory_usage | |
| log_heap_mem_usage | |
| log_perm_gen_usage | |
| sleep calc_sleep_time | |
| end | |
| def log_heap_mem_usage | |
| usage = get_heap_mem_usage | |
| percent = (usage.used / usage.max.to_f) * 100 | |
| LOGGER.info "MM HeapMem: #{format_bytes(usage.used)} / #{format_bytes(usage.max)}" + | |
| " #{sprintf('%#2d', percent)}%" | |
| end | |
| def log_perm_gen_usage | |
| return unless usage = get_perm_gen_usage | |
| percent = (usage.used / usage.max.to_f) * 100 | |
| LOGGER.info "MM PermGen: #{format_bytes(usage.used)} / #{format_bytes(usage.max)}" + | |
| " #{sprintf('%#2d', percent)}%" | |
| end | |
| def log_system_load | |
| return unless load = get_system_load_average | |
| LOGGER.info "OS LoadAvg: #{sprintf "%#9.4f", load.round(4)}" | |
| end | |
| def log_system_load_with_process | |
| return log_system_load unless pcs = get_process_load_percent | |
| return unless sys = get_system_load_average | |
| LOGGER.info "OS LoadAvg: #{sprintf "%#9.4f", sys.round(4)} - " + | |
| "JVM Using: #{sprintf('%#2d', ((pcs * 1000) / 10.0))}%" | |
| end | |
| protected | |
| def get_system_load_average | |
| mem_mx = java.lang.management.ManagementFactory.getOperatingSystemMXBean | |
| avg = mem_mx.getSystemLoadAverage; avg.to_i == -1 ? nil : avg | |
| end | |
| def get_process_load_percent | |
| name = javax.management.ObjectName.getInstance("java.lang:type=OperatingSystem") | |
| list = mbean_server.getAttributes name, ['ProcessCpuLoad'] | |
| return nil if list.empty? | |
| list[0].value # ProcessCpuLoad is the % CPU of current JVM for the system | |
| end | |
| def get_heap_mem_usage | |
| mem_mx = java.lang.management.ManagementFactory.getMemoryMXBean | |
| mem_mx.getHeapMemoryUsage | |
| end | |
| def get_perm_gen_usage | |
| pool_mx = java.lang.management.ManagementFactory.getMemoryPoolMXBeans | |
| pool_mx = pool_mx.find { |pool| pool.name =~ /Perm.?Gen/ } | |
| pool_mx ? pool_mx.getUsage : nil # no Perm Gen on Java 8 | |
| end | |
| def mbean_server | |
| java.lang.management.ManagementFactory.getPlatformMBeanServer | |
| end | |
| # | |
| def calc_sleep_time | |
| normal, three_quart, geting_full = 5, 3, 1.5 # seconds | |
| return normal unless usage = get_perm_gen_usage | |
| return geting_full if (usage.used / usage.max.to_f) >= 0.90 | |
| return three_quart if (usage.used / usage.max.to_f) >= 0.75 | |
| normal | |
| end | |
| private | |
| def format_bytes(count) | |
| sprintf "%#6.1f MB", (count / (1000 * 1024)).round(2) | |
| end | |
| end.new.start if defined? JRUBY_VERSION |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment