1d063d912e5580222b1822b152de315420cef49eeJeff Hao/* 2d063d912e5580222b1822b152de315420cef49eeJeff Hao * Copyright (C) 2014 The Android Open Source Project 3d063d912e5580222b1822b152de315420cef49eeJeff Hao * 4d063d912e5580222b1822b152de315420cef49eeJeff Hao * Licensed under the Apache License, Version 2.0 (the "License"); 5d063d912e5580222b1822b152de315420cef49eeJeff Hao * you may not use this file except in compliance with the License. 6d063d912e5580222b1822b152de315420cef49eeJeff Hao * You may obtain a copy of the License at 7d063d912e5580222b1822b152de315420cef49eeJeff Hao * 8d063d912e5580222b1822b152de315420cef49eeJeff Hao * http://www.apache.org/licenses/LICENSE-2.0 9d063d912e5580222b1822b152de315420cef49eeJeff Hao * 10d063d912e5580222b1822b152de315420cef49eeJeff Hao * Unless required by applicable law or agreed to in writing, software 11d063d912e5580222b1822b152de315420cef49eeJeff Hao * distributed under the License is distributed on an "AS IS" BASIS, 12d063d912e5580222b1822b152de315420cef49eeJeff Hao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d063d912e5580222b1822b152de315420cef49eeJeff Hao * See the License for the specific language governing permissions and 14d063d912e5580222b1822b152de315420cef49eeJeff Hao * limitations under the License. 15d063d912e5580222b1822b152de315420cef49eeJeff Hao */ 16d063d912e5580222b1822b152de315420cef49eeJeff Hao 17d063d912e5580222b1822b152de315420cef49eeJeff Haoimport java.io.File; 18d063d912e5580222b1822b152de315420cef49eeJeff Haoimport java.io.IOException; 19d063d912e5580222b1822b152de315420cef49eeJeff Haoimport java.lang.reflect.Method; 20f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartierimport java.util.Arrays; 21f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartierimport java.util.ArrayList; 22a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchiimport java.util.Map; 23d063d912e5580222b1822b152de315420cef49eeJeff Hao 24d063d912e5580222b1822b152de315420cef49eeJeff Haopublic class Main { 25ef3b17732afb70ac70075a0334cb7074761bd507Sebastien Hertz private static final String TEMP_FILE_NAME_PREFIX = "test"; 26ef3b17732afb70ac70075a0334cb7074761bd507Sebastien Hertz private static final String TEMP_FILE_NAME_SUFFIX = ".trace"; 27ef3b17732afb70ac70075a0334cb7074761bd507Sebastien Hertz 28d063d912e5580222b1822b152de315420cef49eeJeff Hao public static void main(String[] args) throws Exception { 29d063d912e5580222b1822b152de315420cef49eeJeff Hao String name = System.getProperty("java.vm.name"); 30d063d912e5580222b1822b152de315420cef49eeJeff Hao if (!"Dalvik".equals(name)) { 31d063d912e5580222b1822b152de315420cef49eeJeff Hao System.out.println("This test is not supported on " + name); 32d063d912e5580222b1822b152de315420cef49eeJeff Hao return; 33d063d912e5580222b1822b152de315420cef49eeJeff Hao } 34d063d912e5580222b1822b152de315420cef49eeJeff Hao testMethodTracing(); 35f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier testCountInstances(); 36a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi testRuntimeStat(); 37f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier testRuntimeStats(); 38d063d912e5580222b1822b152de315420cef49eeJeff Hao } 39d063d912e5580222b1822b152de315420cef49eeJeff Hao 407403503d9ba33463e850b7e87a1b0430372d7003Andreas Gampe private static File createTempFile() throws Exception { 418cf89c4ac6e09f17093ef0f8c35e86dcd2807d98Jeff Hao try { 42ef3b17732afb70ac70075a0334cb7074761bd507Sebastien Hertz return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX); 438cf89c4ac6e09f17093ef0f8c35e86dcd2807d98Jeff Hao } catch (IOException e) { 447403503d9ba33463e850b7e87a1b0430372d7003Andreas Gampe System.setProperty("java.io.tmpdir", "/data/local/tmp"); 457403503d9ba33463e850b7e87a1b0430372d7003Andreas Gampe try { 46ef3b17732afb70ac70075a0334cb7074761bd507Sebastien Hertz return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX); 477403503d9ba33463e850b7e87a1b0430372d7003Andreas Gampe } catch (IOException e2) { 487403503d9ba33463e850b7e87a1b0430372d7003Andreas Gampe System.setProperty("java.io.tmpdir", "/sdcard"); 49ef3b17732afb70ac70075a0334cb7074761bd507Sebastien Hertz return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX); 507403503d9ba33463e850b7e87a1b0430372d7003Andreas Gampe } 51d063d912e5580222b1822b152de315420cef49eeJeff Hao } 527403503d9ba33463e850b7e87a1b0430372d7003Andreas Gampe } 537403503d9ba33463e850b7e87a1b0430372d7003Andreas Gampe 547403503d9ba33463e850b7e87a1b0430372d7003Andreas Gampe private static void testMethodTracing() throws Exception { 55ef3b17732afb70ac70075a0334cb7074761bd507Sebastien Hertz File tempFile = null; 56ef3b17732afb70ac70075a0334cb7074761bd507Sebastien Hertz try { 57ef3b17732afb70ac70075a0334cb7074761bd507Sebastien Hertz tempFile = createTempFile(); 58ef3b17732afb70ac70075a0334cb7074761bd507Sebastien Hertz testMethodTracingToFile(tempFile); 59ef3b17732afb70ac70075a0334cb7074761bd507Sebastien Hertz } finally { 60ef3b17732afb70ac70075a0334cb7074761bd507Sebastien Hertz if (tempFile != null) { 61ef3b17732afb70ac70075a0334cb7074761bd507Sebastien Hertz tempFile.delete(); 62ef3b17732afb70ac70075a0334cb7074761bd507Sebastien Hertz } 63ef3b17732afb70ac70075a0334cb7074761bd507Sebastien Hertz } 64ef3b17732afb70ac70075a0334cb7074761bd507Sebastien Hertz } 65ef3b17732afb70ac70075a0334cb7074761bd507Sebastien Hertz 66ef3b17732afb70ac70075a0334cb7074761bd507Sebastien Hertz private static void testMethodTracingToFile(File tempFile) throws Exception { 678cf89c4ac6e09f17093ef0f8c35e86dcd2807d98Jeff Hao String tempFileName = tempFile.getPath(); 68d063d912e5580222b1822b152de315420cef49eeJeff Hao 69cbe15be6f108da7f56c7cb481d2cbed9c568d35aJeff Hao if (VMDebug.getMethodTracingMode() != 0) { 70cbe15be6f108da7f56c7cb481d2cbed9c568d35aJeff Hao VMDebug.stopMethodTracing(); 71cbe15be6f108da7f56c7cb481d2cbed9c568d35aJeff Hao } 72cbe15be6f108da7f56c7cb481d2cbed9c568d35aJeff Hao 73d063d912e5580222b1822b152de315420cef49eeJeff Hao System.out.println("Confirm enable/disable"); 74d063d912e5580222b1822b152de315420cef49eeJeff Hao System.out.println("status=" + VMDebug.getMethodTracingMode()); 75d063d912e5580222b1822b152de315420cef49eeJeff Hao VMDebug.startMethodTracing(tempFileName, 0, 0, false, 0); 76d063d912e5580222b1822b152de315420cef49eeJeff Hao System.out.println("status=" + VMDebug.getMethodTracingMode()); 77d063d912e5580222b1822b152de315420cef49eeJeff Hao VMDebug.stopMethodTracing(); 78d063d912e5580222b1822b152de315420cef49eeJeff Hao System.out.println("status=" + VMDebug.getMethodTracingMode()); 79d063d912e5580222b1822b152de315420cef49eeJeff Hao if (tempFile.length() == 0) { 80d063d912e5580222b1822b152de315420cef49eeJeff Hao System.out.println("ERROR: tracing output file is empty"); 81d063d912e5580222b1822b152de315420cef49eeJeff Hao } 82d063d912e5580222b1822b152de315420cef49eeJeff Hao 83d063d912e5580222b1822b152de315420cef49eeJeff Hao System.out.println("Confirm sampling"); 84d063d912e5580222b1822b152de315420cef49eeJeff Hao VMDebug.startMethodTracing(tempFileName, 0, 0, true, 1000); 85d063d912e5580222b1822b152de315420cef49eeJeff Hao System.out.println("status=" + VMDebug.getMethodTracingMode()); 86d063d912e5580222b1822b152de315420cef49eeJeff Hao VMDebug.stopMethodTracing(); 87d063d912e5580222b1822b152de315420cef49eeJeff Hao System.out.println("status=" + VMDebug.getMethodTracingMode()); 88d063d912e5580222b1822b152de315420cef49eeJeff Hao if (tempFile.length() == 0) { 89d063d912e5580222b1822b152de315420cef49eeJeff Hao System.out.println("ERROR: sample tracing output file is empty"); 90d063d912e5580222b1822b152de315420cef49eeJeff Hao } 91d063d912e5580222b1822b152de315420cef49eeJeff Hao 92d063d912e5580222b1822b152de315420cef49eeJeff Hao System.out.println("Test starting when already started"); 93d063d912e5580222b1822b152de315420cef49eeJeff Hao VMDebug.startMethodTracing(tempFileName, 0, 0, false, 0); 94d063d912e5580222b1822b152de315420cef49eeJeff Hao System.out.println("status=" + VMDebug.getMethodTracingMode()); 95d063d912e5580222b1822b152de315420cef49eeJeff Hao VMDebug.startMethodTracing(tempFileName, 0, 0, false, 0); 96d063d912e5580222b1822b152de315420cef49eeJeff Hao System.out.println("status=" + VMDebug.getMethodTracingMode()); 97d063d912e5580222b1822b152de315420cef49eeJeff Hao 98d063d912e5580222b1822b152de315420cef49eeJeff Hao System.out.println("Test stopping when already stopped"); 99d063d912e5580222b1822b152de315420cef49eeJeff Hao VMDebug.stopMethodTracing(); 100d063d912e5580222b1822b152de315420cef49eeJeff Hao System.out.println("status=" + VMDebug.getMethodTracingMode()); 101d063d912e5580222b1822b152de315420cef49eeJeff Hao VMDebug.stopMethodTracing(); 102d063d912e5580222b1822b152de315420cef49eeJeff Hao System.out.println("status=" + VMDebug.getMethodTracingMode()); 103d063d912e5580222b1822b152de315420cef49eeJeff Hao 104d063d912e5580222b1822b152de315420cef49eeJeff Hao System.out.println("Test tracing with empty filename"); 105d063d912e5580222b1822b152de315420cef49eeJeff Hao try { 106d063d912e5580222b1822b152de315420cef49eeJeff Hao VMDebug.startMethodTracing("", 0, 0, false, 0); 107d063d912e5580222b1822b152de315420cef49eeJeff Hao System.out.println("Should have thrown an exception"); 108d063d912e5580222b1822b152de315420cef49eeJeff Hao } catch (Exception e) { 109d063d912e5580222b1822b152de315420cef49eeJeff Hao System.out.println("Got expected exception"); 110d063d912e5580222b1822b152de315420cef49eeJeff Hao } 111d063d912e5580222b1822b152de315420cef49eeJeff Hao 112d063d912e5580222b1822b152de315420cef49eeJeff Hao System.out.println("Test tracing with bogus (< 1024 && != 0) filesize"); 113d063d912e5580222b1822b152de315420cef49eeJeff Hao try { 114d063d912e5580222b1822b152de315420cef49eeJeff Hao VMDebug.startMethodTracing(tempFileName, 1000, 0, false, 0); 115d063d912e5580222b1822b152de315420cef49eeJeff Hao System.out.println("Should have thrown an exception"); 116d063d912e5580222b1822b152de315420cef49eeJeff Hao } catch (Exception e) { 117d063d912e5580222b1822b152de315420cef49eeJeff Hao System.out.println("Got expected exception"); 118d063d912e5580222b1822b152de315420cef49eeJeff Hao } 119d063d912e5580222b1822b152de315420cef49eeJeff Hao 120d063d912e5580222b1822b152de315420cef49eeJeff Hao System.out.println("Test sampling with bogus (<= 0) interval"); 121d063d912e5580222b1822b152de315420cef49eeJeff Hao try { 122d063d912e5580222b1822b152de315420cef49eeJeff Hao VMDebug.startMethodTracing(tempFileName, 0, 0, true, 0); 123d063d912e5580222b1822b152de315420cef49eeJeff Hao System.out.println("Should have thrown an exception"); 124d063d912e5580222b1822b152de315420cef49eeJeff Hao } catch (Exception e) { 125d063d912e5580222b1822b152de315420cef49eeJeff Hao System.out.println("Got expected exception"); 126d063d912e5580222b1822b152de315420cef49eeJeff Hao } 127d063d912e5580222b1822b152de315420cef49eeJeff Hao 128d063d912e5580222b1822b152de315420cef49eeJeff Hao tempFile.delete(); 129d063d912e5580222b1822b152de315420cef49eeJeff Hao } 130d063d912e5580222b1822b152de315420cef49eeJeff Hao 131a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi private static void checkNumber(String s) throws Exception { 132a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi if (s == null) { 133a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi System.out.println("Got null string"); 134a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi return; 135a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 136a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi long n = Long.valueOf(s); 137a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi if (n < 0) { 138a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi System.out.println("Got negative number " + n); 139a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 140a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 141a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi 142a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi private static void checkHistogram(String s) throws Exception { 143a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi if (s == null || s.length() == 0) { 144a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi System.out.println("Got null or empty string"); 145a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi return; 146a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 147a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi String[] buckets = s.split(","); 148a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi long last_key = 0; 149a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi for (int i = 0; i < buckets.length; ++i) { 150a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi String bucket = buckets[i]; 151a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi if (bucket.length() == 0) { 152a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi System.out.println("Got empty bucket"); 153a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi continue; 154a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 155a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi String[] kv = bucket.split(":"); 156a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi if (kv.length != 2 || kv[0].length() == 0 || kv[1].length() == 0) { 157a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi System.out.println("Got bad bucket " + bucket); 158a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi continue; 159a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 160a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi long key = Long.valueOf(kv[0]); 161a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi long value = Long.valueOf(kv[1]); 162a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi if (key < 0 || value < 0) { 163a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi System.out.println("Got negative key or value " + bucket); 164a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi continue; 165a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 166a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi if (key < last_key) { 167a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi System.out.println("Got decreasing key " + bucket); 168a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi continue; 169a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 170a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi last_key = key; 171a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 172a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 173a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi 174a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi private static void testRuntimeStat() throws Exception { 175a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi // Invoke at least one GC and wait for 20 seconds or so so we get at 176a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi // least one bucket in the histograms. 177a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi for (int i = 0; i < 20; ++i) { 178a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi Runtime.getRuntime().gc(); 179a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi Thread.sleep(1000L); 180a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 181a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi String gc_count = VMDebug.getRuntimeStat("art.gc.gc-count"); 182a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi String gc_time = VMDebug.getRuntimeStat("art.gc.gc-time"); 183a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi String bytes_allocated = VMDebug.getRuntimeStat("art.gc.bytes-allocated"); 184a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi String bytes_freed = VMDebug.getRuntimeStat("art.gc.bytes-freed"); 185a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi String blocking_gc_count = VMDebug.getRuntimeStat("art.gc.blocking-gc-count"); 186a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi String blocking_gc_time = VMDebug.getRuntimeStat("art.gc.blocking-gc-time"); 187a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi String gc_count_rate_histogram = VMDebug.getRuntimeStat("art.gc.gc-count-rate-histogram"); 188a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi String blocking_gc_count_rate_histogram = 189a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi VMDebug.getRuntimeStat("art.gc.blocking-gc-count-rate-histogram"); 190a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi checkNumber(gc_count); 191a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi checkNumber(gc_time); 192a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi checkNumber(bytes_allocated); 193a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi checkNumber(bytes_freed); 194a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi checkNumber(blocking_gc_count); 195a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi checkNumber(blocking_gc_time); 196a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi checkHistogram(gc_count_rate_histogram); 197a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi checkHistogram(blocking_gc_count_rate_histogram); 198a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 199a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi 200a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi private static void testRuntimeStats() throws Exception { 201a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi // Invoke at least one GC and wait for 20 seconds or so so we get at 202a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi // least one bucket in the histograms. 203a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi for (int i = 0; i < 20; ++i) { 204a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi Runtime.getRuntime().gc(); 205a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi Thread.sleep(1000L); 206a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 207a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi Map<String, String> map = VMDebug.getRuntimeStats(); 208a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi String gc_count = map.get("art.gc.gc-count"); 209a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi String gc_time = map.get("art.gc.gc-time"); 210a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi String bytes_allocated = map.get("art.gc.bytes-allocated"); 211a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi String bytes_freed = map.get("art.gc.bytes-freed"); 212a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi String blocking_gc_count = map.get("art.gc.blocking-gc-count"); 213a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi String blocking_gc_time = map.get("art.gc.blocking-gc-time"); 214a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi String gc_count_rate_histogram = map.get("art.gc.gc-count-rate-histogram"); 215a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi String blocking_gc_count_rate_histogram = 216a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi map.get("art.gc.blocking-gc-count-rate-histogram"); 217a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi checkNumber(gc_count); 218a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi checkNumber(gc_time); 219a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi checkNumber(bytes_allocated); 220a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi checkNumber(bytes_freed); 221a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi checkNumber(blocking_gc_count); 222a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi checkNumber(blocking_gc_time); 223a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi checkHistogram(gc_count_rate_histogram); 224a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi checkHistogram(blocking_gc_count_rate_histogram); 225a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 226a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi 227f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier static class ClassA { } 228f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier static class ClassB { } 229f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier static class ClassC extends ClassA { } 230f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier 231f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier private static void testCountInstances() throws Exception { 232f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier ArrayList<Object> l = new ArrayList<Object>(); 233f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier l.add(new ClassA()); 234f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier l.add(new ClassB()); 235f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier l.add(new ClassA()); 236f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier l.add(new ClassC()); 237f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier Runtime.getRuntime().gc(); 238f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier System.out.println("Instances of ClassA " + 239f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier VMDebug.countInstancesofClass(ClassA.class, false)); 240f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier System.out.println("Instances of ClassB " + 241f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier VMDebug.countInstancesofClass(ClassB.class, false)); 242f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier System.out.println("Instances of null " + VMDebug.countInstancesofClass(null, false)); 243f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier System.out.println("Instances of ClassA assignable " + 244f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier VMDebug.countInstancesofClass(ClassA.class, true)); 245f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier Class[] classes = new Class[]{ClassA.class, ClassB.class, null}; 246f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier long[] counts = VMDebug.countInstancesofClasses(classes, false); 247f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier System.out.println("Array counts " + Arrays.toString(counts)); 248f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier counts = VMDebug.countInstancesofClasses(classes, true); 249f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier System.out.println("Array counts assignable " + Arrays.toString(counts)); 250f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier } 251f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier 252d063d912e5580222b1822b152de315420cef49eeJeff Hao private static class VMDebug { 253d063d912e5580222b1822b152de315420cef49eeJeff Hao private static final Method startMethodTracingMethod; 254d063d912e5580222b1822b152de315420cef49eeJeff Hao private static final Method stopMethodTracingMethod; 255d063d912e5580222b1822b152de315420cef49eeJeff Hao private static final Method getMethodTracingModeMethod; 256a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi private static final Method getRuntimeStatMethod; 257a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi private static final Method getRuntimeStatsMethod; 258f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier private static final Method countInstancesOfClassMethod; 259f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier private static final Method countInstancesOfClassesMethod; 260d063d912e5580222b1822b152de315420cef49eeJeff Hao static { 261d063d912e5580222b1822b152de315420cef49eeJeff Hao try { 262d063d912e5580222b1822b152de315420cef49eeJeff Hao Class c = Class.forName("dalvik.system.VMDebug"); 263d063d912e5580222b1822b152de315420cef49eeJeff Hao startMethodTracingMethod = c.getDeclaredMethod("startMethodTracing", String.class, 264d063d912e5580222b1822b152de315420cef49eeJeff Hao Integer.TYPE, Integer.TYPE, Boolean.TYPE, Integer.TYPE); 265d063d912e5580222b1822b152de315420cef49eeJeff Hao stopMethodTracingMethod = c.getDeclaredMethod("stopMethodTracing"); 266d063d912e5580222b1822b152de315420cef49eeJeff Hao getMethodTracingModeMethod = c.getDeclaredMethod("getMethodTracingMode"); 267a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi getRuntimeStatMethod = c.getDeclaredMethod("getRuntimeStat", String.class); 268a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi getRuntimeStatsMethod = c.getDeclaredMethod("getRuntimeStats"); 269f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier countInstancesOfClassMethod = c.getDeclaredMethod("countInstancesOfClass", 270f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier Class.class, Boolean.TYPE); 271f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier countInstancesOfClassesMethod = c.getDeclaredMethod("countInstancesOfClasses", 272f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier Class[].class, Boolean.TYPE); 273d063d912e5580222b1822b152de315420cef49eeJeff Hao } catch (Exception e) { 274d063d912e5580222b1822b152de315420cef49eeJeff Hao throw new RuntimeException(e); 275d063d912e5580222b1822b152de315420cef49eeJeff Hao } 276d063d912e5580222b1822b152de315420cef49eeJeff Hao } 277d063d912e5580222b1822b152de315420cef49eeJeff Hao 278d063d912e5580222b1822b152de315420cef49eeJeff Hao public static void startMethodTracing(String filename, int bufferSize, int flags, 279d063d912e5580222b1822b152de315420cef49eeJeff Hao boolean samplingEnabled, int intervalUs) throws Exception { 280d063d912e5580222b1822b152de315420cef49eeJeff Hao startMethodTracingMethod.invoke(null, filename, bufferSize, flags, samplingEnabled, 281d063d912e5580222b1822b152de315420cef49eeJeff Hao intervalUs); 282d063d912e5580222b1822b152de315420cef49eeJeff Hao } 283d063d912e5580222b1822b152de315420cef49eeJeff Hao public static void stopMethodTracing() throws Exception { 284d063d912e5580222b1822b152de315420cef49eeJeff Hao stopMethodTracingMethod.invoke(null); 285d063d912e5580222b1822b152de315420cef49eeJeff Hao } 286d063d912e5580222b1822b152de315420cef49eeJeff Hao public static int getMethodTracingMode() throws Exception { 287d063d912e5580222b1822b152de315420cef49eeJeff Hao return (int) getMethodTracingModeMethod.invoke(null); 288d063d912e5580222b1822b152de315420cef49eeJeff Hao } 289a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi public static String getRuntimeStat(String statName) throws Exception { 290a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi return (String) getRuntimeStatMethod.invoke(null, statName); 291a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 292a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi public static Map<String, String> getRuntimeStats() throws Exception { 293a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi return (Map<String, String>) getRuntimeStatsMethod.invoke(null); 294a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 295f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier public static long countInstancesofClass(Class c, boolean assignable) throws Exception { 296f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier return (long) countInstancesOfClassMethod.invoke(null, new Object[]{c, assignable}); 297f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier } 298f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier public static long[] countInstancesofClasses(Class[] classes, boolean assignable) 299f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier throws Exception { 300f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier return (long[]) countInstancesOfClassesMethod.invoke( 301f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier null, new Object[]{classes, assignable}); 302f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier } 303d063d912e5580222b1822b152de315420cef49eeJeff Hao } 304d063d912e5580222b1822b152de315420cef49eeJeff Hao} 305