LoadSet.java

1    package nsu.fit.javaperf; 
2     
3    import java.io.Console; 
4    import java.io.PrintWriter; 
5    import java.io.StringReader; 
6    import java.lang.management.ManagementFactory; 
7    import java.lang.management.RuntimeMXBean; 
8    import java.util.ArrayList; 
9    import java.util.LinkedList; 
10   import java.util.List; 
11   import java.util.Scanner; 
12   import java.util.concurrent.atomic.AtomicLong; 
13    
14   /** 
15    * JVM load-set tests 
16    */ 
17   public class LoadSet { 
18    
19       static final Object rlock = new Object(); 
20    
21       static List<Task> tasks = new ArrayList<>(); //Tasks for runner 
22    
23       static GarbageProducer garbageProducer; 
24    
25    
26       static class Garbage { 
27           private List list = new LinkedList(); 
28    
29           Garbage() { 
30               for (int i = 0; i < 5; i++) { 
31                   list.add(new byte[1]); 
32               } 
33           } 
34       } 
35    
36       static class GarbageProducer extends Thread { 
37    
38           private List<Garbage> garbageStorage; 
39    
40           AtomicLong garbageRemovePeriod = new AtomicLong(150); 
41    
42           AtomicLong garbageAmount = new AtomicLong(50000); 
43    
44           private volatile boolean stopped; 
45    
46           GarbageProducer() { 
47               super("GarbageProducer"); 
48           } 
49    
50           public void run() { 
51               garbageStorage = new ArrayList<>(); 
52               try { 
53                   // период удаления созданного мусора 
54                   long lastGarbageRemoveTime = System.currentTimeMillis(); 
55    
56                   // количество мусора, создаваемого за одну итерацию 
57                   while (!stopped) { 
58                       for (int i = 0; i < garbageAmount.longValue(); i++) { 
59                           garbageStorage.add(new Garbage()); 
60                       } 
61                       if (System.currentTimeMillis() > (lastGarbageRemoveTime + garbageRemovePeriod.longValue())) { 
62                           garbageStorage.clear(); 
63                           Thread.sleep(100); 
64                           lastGarbageRemoveTime = System.currentTimeMillis(); 
65                       } 
66                   } 
67                   garbageStorage.clear(); 
68                   garbageStorage = null; 
69    
70               } catch (InterruptedException e) { 
71                   e.printStackTrace(); 
72               } 
73           } 
74    
75           public void stopGarbageProducer() { 
76               stopped = true; 
77           } 
78       } 
79    
80    
81       static class Task { 
82           final String name; 
83           final String cmdline; 
84    
85           Task(String name) { 
86               this.name = name; 
87               this.cmdline = name; 
88           } 
89    
90           Task(String name, String cmdline) { 
91               this.name = name; 
92               this.cmdline = cmdline; 
93           } 
94    
95           public String toString() { 
96               final StringBuilder sb = new StringBuilder("Task{"); 
97               sb.append("name='").append(name).append('\''); 
98               sb.append(", cmdline='").append(cmdline).append('\''); 
99               sb.append('}'); 
100              return sb.toString(); 
101          } 
102      } 
103   
104      static class TaskRunner implements Runnable { 
105   
106          TaskRunner() { 
107          } 
108   
109          void clear() { 
110              System.err.printf("[%s]: Clearing all allocated memory\n", Thread.currentThread().getName()); 
111              garbageProducer.stopGarbageProducer(); 
112          } 
113   
114          static void yg(String cmd) { 
115              Scanner s = new Scanner(new StringReader(cmd)); 
116              String t = s.next(); 
117              long amount = 0; 
118              if (s.hasNextLong()) { 
119                  amount = s.nextLong(); 
120              } 
121              long rperiod = 0; 
122              if (s.hasNextLong()) { 
123                  rperiod = s.nextLong(); 
124              } 
125              if (rperiod > 0) { 
126                  garbageProducer.garbageRemovePeriod.set(rperiod); 
127              } 
128              if (amount > 0) { 
129                  garbageProducer.garbageAmount.set(amount); 
130              } 
131              if (garbageProducer == null || !garbageProducer.isAlive()) { 
132                  garbageProducer = new GarbageProducer(); 
133                  garbageProducer.start(); 
134              } 
135              System.err.printf("Young garbage generator: amount: %d, rm period: %d\n", 
136                                garbageProducer.garbageAmount.longValue(), 
137                                garbageProducer.garbageRemovePeriod.longValue()); 
138          } 
139   
140          public void run() { 
141              boolean active = true; 
142              while (active) { 
143                  Task task; 
144                  synchronized (rlock) { 
145                      if (tasks.isEmpty()) { 
146                          try { 
147                              rlock.wait(); 
148                          } catch (InterruptedException e) { 
149                              e.printStackTrace(); 
150                              continue; 
151                          } 
152                      } 
153                      if (!tasks.isEmpty()) { 
154                          task = tasks.remove(0); 
155                      } else { 
156                          continue; 
157                      } 
158                  } 
159                  String tn = task.name; 
160                  switch (tn) { 
161                      case "exit": 
162                          active = false; 
163                          break; 
164                      case "clear": 
165                          clear(); 
166                          break; 
167                      case "yg": 
168                          yg(task.cmdline); 
169                          break; 
170                      case "ygs": 
171                          System.err.println("Stopping young garbage generator"); 
172                          garbageProducer.stopGarbageProducer(); 
173                          break; 
174                  } 
175              } 
176          } 
177      } 
178   
179      static void sendTask(Task t) { 
180          synchronized (rlock) { 
181              tasks.add(t); 
182              rlock.notify(); 
183          } 
184      } 
185   
186      static void info(Console c, boolean memonly) { 
187          PrintWriter w = c.writer(); 
188          Runtime rt = Runtime.getRuntime(); 
189          w.printf("Max memory: %d (%dMb)\n", rt.maxMemory(), (int) (rt.maxMemory() / (1024 * 1024))); 
190          w.printf("Total memory: %d (%dMb)\n", rt.totalMemory(), (int) (rt.totalMemory() / (1024 * 1024))); 
191          w.printf("Free memory: %d (%dMb)\n", rt.freeMemory(), (int) (rt.freeMemory() / (1024 * 1024))); 
192   
193   
194          if (!memonly) { 
195              RuntimeMXBean rtMx = ManagementFactory.getRuntimeMXBean(); 
196              List<String> jargs = rtMx.getInputArguments(); 
197              StringBuilder sb = new StringBuilder(); 
198              for (int i = 0; i < jargs.size(); ++i) { 
199                  if (i > 0) { 
200                      sb.append(", "); 
201                  } 
202                  sb.append(jargs.get(i)); 
203              } 
204              w.printf("[%s] %s %s %s (%s)\n", rtMx.getName(), rtMx.getVmName(), rtMx.getVmVendor(), rtMx.getSpecVersion(), rtMx.getVmVersion()); 
205              w.println("JVM args: " + sb); 
206          } 
207          if (garbageProducer != null) { 
208              w.printf("Young garbage generator: %s, amount: %d, rm period: %d\n", 
209                       garbageProducer.isAlive() ? "ACTIVE" : "NOT ACTIVE", 
210                       garbageProducer.garbageAmount.longValue(), 
211                       garbageProducer.garbageRemovePeriod.longValue()); 
212          } else { 
213              w.printf("Young garbage generator: NOT ACTIVE\n"); 
214          } 
215          w.flush(); 
216      } 
217   
218   
219      static void help(Console c) { 
220          PrintWriter w = c.writer(); 
221          w.println("\t Available commmands:\n"); 
222          w.println("\t?|h|help: Print this help."); 
223          w.println("\tq|quit|exit: Exit peogram."); 
224          w.println("\ti|info: Show brief system info."); 
225          w.println("\tgc: Run GC."); 
226          w.println("\tclear: Clear all memory allocated by TaskRunner."); 
227          w.println("\tyg [amount] [removeperiod]: Start generate young garbage. By default amount: 50000, removeperiod: 150ms"); 
228          w.println("\tyg stop: Stop young garbage generator"); 
229          w.flush(); 
230      } 
231   
232      public static void main(String[] args) throws Exception { 
233          Console c = System.console(); 
234          if (c == null) { 
235              System.err.println("Java program cannot open interactive console"); 
236              System.exit(1); 
237          } 
238   
239          Thread tf = new Thread(new TaskRunner()); 
240          tf.setName("TaskThread"); 
241          tf.start(); 
242   
243          PrintWriter w = c.writer(); 
244          w.println("Welcome to JVM load set."); 
245          String cmd; 
246          while ((cmd = c.readLine("> ")) != null) { 
247              cmd = cmd.trim(); 
248              switch (cmd) { 
249                  case "?": 
250                  case "h": 
251                  case "help": 
252                      help(c); 
253                      break; 
254                  case "q": 
255                  case "quit": 
256                  case "exit": 
257                      if (garbageProducer != null && garbageProducer.isAlive()) { 
258                          garbageProducer.stopGarbageProducer(); 
259                          garbageProducer.join(1000); 
260                      } 
261                      sendTask(new Task("exit")); 
262                      tf.join(1000); 
263                      System.exit(0); 
264                      break; 
265                  case "i": 
266                  case "info": 
267                      info(c, false); 
268                      break; 
269                  case "gc": 
270                      w.println("Before GC:"); 
271                      info(c, true); 
272                      for (int i = 0; i < 2; ++i) { 
273                          Runtime.getRuntime().gc(); 
274                          Thread.sleep(100); 
275                      } 
276                      w.println("After GC:"); 
277                      info(c, true); 
278                      break; 
279                  case "clear": 
280                      sendTask(new Task(cmd)); 
281                      break; 
282                  default: 
283                      if (cmd.startsWith("yg")) { 
284                          if (cmd.matches("yg\\s+stop")) { 
285                              sendTask(new Task("ygs", cmd)); 
286                          } else { 
287                              sendTask(new Task("yg", cmd)); 
288                          } 
289                      } 
290                      break; 
291   
292              } 
293          } 
294      } 
295  } 
296