34 try {
35 System.loadLibrary("HeapMonitor");
36 } catch (UnsatisfiedLinkError ule) {
37 System.err.println("Could not load HeapMonitor library");
38 System.err.println("java.library.path: " + System.getProperty("java.library.path"));
39 throw ule;
40 }
41 }
42
43 /** Enable heap monitoring sampling with default value for rate. */
44 public static void enableSamplingRate() {
45 setSamplingRate(1 << 19);
46 }
47
48 public static void disableSamplingRate() {
49 setSamplingRate(0);
50 }
51
52 /** Set a specific sampling rate, 0 turns off sampling. */
53 public native static void setSamplingRate(int rate);
54
55 public native static void enableSamplingEvents();
56 public native static void disableSamplingEvents();
57
58 /**
59 * Allocate memory but first create a stack trace of a particular depth.
60 *
61 * @return list of frames for the allocation.
62 */
63 public static List<Frame> allocate(int depth) {
64 List<Frame> frames = new ArrayList<Frame>();
65 if (depth > 1) {
66 createStackDepth(depth - 1, frames);
67 frames.add(new Frame("allocate", "(I)Ljava/util/List;", "HeapMonitor.java", 61));
68 } else {
69 actuallyAllocate();
70 frames.add(new Frame("actuallyAllocate", "()I", "HeapMonitor.java", 126));
71 frames.add(new Frame("allocate", "(I)Ljava/util/List;", "HeapMonitor.java", 64));
72 }
73 return frames;
74 }
75
76 /**
77 * Allocate memory but first create a stack trace.
78 *
79 * @return list of frames for the allocation.
80 */
81 public static List<Frame> allocate() {
82 int sum = 0;
83 List<Frame> frames = new ArrayList<Frame>();
84 allocate(frames);
85 frames.add(new Frame("allocate", "()Ljava/util/List;", "HeapMonitor.java", 79));
86 return frames;
87 }
88
89 private static void createStackDepth(int depth, List<Frame> frames) {
90 if (depth > 1) {
91 createStackDepth(depth - 1, frames);
92 frames.add(new Frame("createStackDepth", "(ILjava/util/List;)V", "HeapMonitor.java", 86));
93 } else {
94 allocate(frames);
95 frames.add(new Frame("createStackDepth", "(ILjava/util/List;)V", "HeapMonitor.java", 89));
96 }
97 }
98
99 private static void allocate(List<Frame> frames) {
100 int sum = 0;
101 for (int j = 0; j < 1000; j++) {
102 sum += actuallyAllocate();
103 }
104 frames.add(new Frame("actuallyAllocate", "()I", "HeapMonitor.java", 124));
105 frames.add(new Frame("allocate", "(Ljava/util/List;)V", "HeapMonitor.java", 97));
106 }
107
108 public static List<Frame> repeatAllocate(int max) {
109 List<Frame> frames = null;
110 for (int i = 0; i < max; i++) {
111 frames = allocate();
112 }
113 frames.add(new Frame("repeatAllocate", "(I)Ljava/util/List;", "HeapMonitor.java", 106));
114 return frames;
115 }
116
117 private static int actuallyAllocate() {
118 int sum = 0;
119
120 // Let us assume that a 1-element array is 24 bytes of memory and we want
121 // 2MB allocated.
122 int iterations = (1 << 19) / 6;
123
124 if (arrays == null) {
125 arrays = new int[iterations][];
126 }
127
128 for (int i = 0; i < iterations; i++) {
129 int tmp[] = new int[1];
130 // Force it to be kept and, at the same time, wipe out any previous data.
131 arrays[i] = tmp;
132 sum += arrays[0][0];
133 }
134 return sum;
135 }
136
137 /** Remove the reference to the global array to free data at the next GC. */
138 public static void freeStorage() {
139 arrays = null;
140 }
141
142 public native static boolean obtainedEvents(Frame[] frames);
143 public native static boolean eventStorageIsEmpty();
144 public native static void resetEventStorage();
145 }
|
34 try {
35 System.loadLibrary("HeapMonitor");
36 } catch (UnsatisfiedLinkError ule) {
37 System.err.println("Could not load HeapMonitor library");
38 System.err.println("java.library.path: " + System.getProperty("java.library.path"));
39 throw ule;
40 }
41 }
42
43 /** Enable heap monitoring sampling with default value for rate. */
44 public static void enableSamplingRate() {
45 setSamplingRate(1 << 19);
46 }
47
48 public static void disableSamplingRate() {
49 setSamplingRate(0);
50 }
51
52 /** Set a specific sampling rate, 0 turns off sampling. */
53 public native static void setSamplingRate(int rate);
54 /** Set a specific garbage history buffer. */
55 public native static void setGarbageHistory(int amount);
56
57 public native static void enableSamplingEvents();
58 public native static void disableSamplingEvents();
59
60 /**
61 * Allocate memory but first create a stack trace of a particular depth.
62 *
63 * @return list of frames for the allocation.
64 */
65 public static List<Frame> allocate(int depth) {
66 List<Frame> frames = new ArrayList<Frame>();
67 if (depth > 1) {
68 createStackDepth(depth - 1, frames);
69 frames.add(new Frame("allocate", "(I)Ljava/util/List;", "HeapMonitor.java", 68));
70 } else {
71 actuallyAllocate();
72 frames.add(new Frame("actuallyAllocate", "()I", "HeapMonitor.java", 131));
73 frames.add(new Frame("allocate", "(I)Ljava/util/List;", "HeapMonitor.java", 71));
74 }
75 return frames;
76 }
77
78 /**
79 * Allocate memory but first create a stack trace.
80 *
81 * @return list of frames for the allocation.
82 */
83 public static List<Frame> allocate() {
84 int sum = 0;
85 List<Frame> frames = new ArrayList<Frame>();
86 allocate(frames);
87 frames.add(new Frame("allocate", "()Ljava/util/List;", "HeapMonitor.java", 86));
88 return frames;
89 }
90
91 private static void createStackDepth(int depth, List<Frame> frames) {
92 if (depth > 1) {
93 createStackDepth(depth - 1, frames);
94 frames.add(new Frame("createStackDepth", "(ILjava/util/List;)V", "HeapMonitor.java", 93));
95 } else {
96 allocate(frames);
97 frames.add(new Frame("createStackDepth", "(ILjava/util/List;)V", "HeapMonitor.java", 96));
98 }
99 }
100
101 private static void allocate(List<Frame> frames) {
102 int sum = 0;
103 for (int j = 0; j < 1000; j++) {
104 sum += actuallyAllocate();
105 }
106 frames.add(new Frame("actuallyAllocate", "()I", "HeapMonitor.java", 131));
107 frames.add(new Frame("allocate", "(Ljava/util/List;)V", "HeapMonitor.java", 104));
108 }
109
110 public static List<Frame> repeatAllocate(int max) {
111 List<Frame> frames = null;
112 for (int i = 0; i < max; i++) {
113 frames = allocate();
114 }
115 frames.add(new Frame("repeatAllocate", "(I)Ljava/util/List;", "HeapMonitor.java", 113));
116 return frames;
117 }
118
119 private static int actuallyAllocate() {
120 int sum = 0;
121
122 // Let us assume that a 1-element array is 24 bytes of memory and we want
123 // 2MB allocated.
124 int iterations = (1 << 19) / 6;
125
126 if (arrays == null) {
127 arrays = new int[iterations][];
128 }
129
130 for (int i = 0; i < iterations; i++) {
131 int tmp[] = new int[1];
132 // Force it to be kept and, at the same time, wipe out any previous data.
133 arrays[i] = tmp;
134 sum += arrays[0][0];
135 }
136 return sum;
137 }
138
139 public static int allocateSize(int totalSize) {
140 int sum = 0;
141
142 // Let us assume that a 1-element array is 24 bytes.
143 int iterations = totalSize / 24;
144
145 if (arrays == null) {
146 arrays = new int[iterations][];
147 }
148
149 System.out.println("Allocating for " + iterations);
150 for (int i = 0; i < iterations; i++) {
151 int tmp[] = new int[1];
152
153 // Force it to be kept and, at the same time, wipe out any previous data.
154 arrays[i] = tmp;
155 sum += arrays[0][0];
156 }
157
158 return sum;
159 }
160
161 /** Remove the reference to the global array to free data at the next GC. */
162 public static void freeStorage() {
163 arrays = null;
164 }
165
166 public native static boolean obtainedEvents(Frame[] frames);
167 public native static boolean garbageContains(Frame[] frames);
168 public native static boolean eventStorageIsEmpty();
169 public native static void resetEventStorage();
170 public native static int getEventStorageElementCount();
171 public native static void forceGarbageCollection();
172
173 public static boolean statsHaveExpectedNumberSamples(int expected, int acceptedErrorPercentage) {
174 double actual = getEventStorageElementCount();
175 double diffPercentage = Math.abs(actual - expected) / expected;
176 return diffPercentage < acceptedErrorPercentage;
177 }
178 }
|