133 |
133 |
134 return defineClass(name, b, 0, b.length); |
134 return defineClass(name, b, 0, b.length); |
135 } |
135 } |
136 |
136 |
137 /* |
137 /* |
138 * Run method for thread that continuously loads classes. |
138 * Load classes until MemoryPoolMXBean.getUsageThresholdCount() > 0. |
139 * |
139 * Then wait for the memory threshold notification to be received. |
140 * Note: Once the usage threshold has been exceeded the low memory |
|
141 * detector thread will attempt to deliver its notification - this can |
|
142 * potentially create a race condition with this thread contining to |
|
143 * fill up metaspace. To avoid the low memory detector getting an |
|
144 * OutOfMemory we throttle this thread once the threshold has been |
|
145 * exceeded. |
|
146 */ |
140 */ |
147 public void run() { |
141 public void run() { |
148 List pools = ManagementFactory.getMemoryPoolMXBeans(); |
142 List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans(); |
149 boolean thresholdExceeded = false; |
143 boolean thresholdExceeded = false; |
150 |
144 |
151 for (;;) { |
145 // Load classes until MemoryPoolMXBean.getUsageThresholdCount() > 0 |
152 try { |
146 while (!thresholdExceeded) { |
153 // the classes are small so we load 10 at a time |
147 // the classes are small so we load 10 at a time |
154 for (int i=0; i<10; i++) { |
148 for (int i=0; i<10; i++) { |
155 loadNext(); |
149 loadNext(); |
156 } |
|
157 } catch (ClassNotFoundException x) { |
|
158 return; |
|
159 } |
150 } |
160 if (listenerInvoked) { |
151 |
161 return; |
152 // check if the threshold has been exceeded |
162 } |
153 for (MemoryPoolMXBean p : pools) { |
163 |
154 if (p.getType() == MemoryType.NON_HEAP && |
164 // if threshold has been exceeded we put in a delay to allow |
155 p.isUsageThresholdSupported() && |
165 // the low memory detector do its job. |
156 p.getUsageThresholdCount() > 0) |
166 if (thresholdExceeded) { |
157 { |
167 try { |
158 thresholdExceeded = true; |
168 Thread.currentThread().sleep(100); |
159 break; |
169 } catch (InterruptedException x) { } |
|
170 } else { |
|
171 // check if the threshold has been exceeded |
|
172 ListIterator i = pools.listIterator(); |
|
173 while (i.hasNext()) { |
|
174 MemoryPoolMXBean p = (MemoryPoolMXBean) i.next(); |
|
175 if (p.getType() == MemoryType.NON_HEAP && |
|
176 p.isUsageThresholdSupported()) |
|
177 { |
|
178 thresholdExceeded = p.isUsageThresholdExceeded(); |
|
179 } |
|
180 } |
160 } |
181 } |
161 } |
182 } |
162 } |
|
163 |
|
164 System.out.println("thresholdExceeded. Waiting for notification"); |
|
165 while (!listenerInvoked) { |
|
166 try { |
|
167 Thread.currentThread().sleep(10); |
|
168 } catch (InterruptedException x) {} |
|
169 } |
183 } |
170 } |
184 } |
171 } |
185 |
172 |
186 public static void main(String args[]) { |
173 public static void main(String args[]) { |
187 ListIterator iter = ManagementFactory.getMemoryPoolMXBeans().listIterator(); |
174 List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans(); |
188 |
175 |
189 // Set threshold of 80% of all NON_HEAP memory pools |
176 // Set threshold of 80% of all NON_HEAP memory pools |
190 // In the Hotspot implementation this means we should get a notification |
177 // In the Hotspot implementation this means we should get a notification |
191 // if the CodeCache or metaspace fills up. |
178 // if the CodeCache or metaspace fills up. |
192 |
179 |
193 while (iter.hasNext()) { |
180 for (MemoryPoolMXBean p : pools) { |
194 MemoryPoolMXBean p = (MemoryPoolMXBean) iter.next(); |
|
195 if (p.getType() == MemoryType.NON_HEAP && p.isUsageThresholdSupported()) { |
181 if (p.getType() == MemoryType.NON_HEAP && p.isUsageThresholdSupported()) { |
196 |
182 |
197 // set threshold |
183 // set threshold |
198 MemoryUsage mu = p.getUsage(); |
184 MemoryUsage mu = p.getUsage(); |
199 long max = mu.getMax(); |
185 long max = mu.getMax(); |