J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame^] | 1 | <!-- |
| 2 | Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. |
| 3 | DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| 4 | |
| 5 | This code is free software; you can redistribute it and/or modify it |
| 6 | under the terms of the GNU General Public License version 2 only, as |
| 7 | published by the Free Software Foundation. Sun designates this |
| 8 | particular file as subject to the "Classpath" exception as provided |
| 9 | by Sun in the LICENSE file that accompanied this code. |
| 10 | |
| 11 | This code is distributed in the hope that it will be useful, but WITHOUT |
| 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 13 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| 14 | version 2 for more details (a copy is included in the LICENSE file that |
| 15 | accompanied this code). |
| 16 | |
| 17 | You should have received a copy of the GNU General Public License version |
| 18 | 2 along with this work; if not, write to the Free Software Foundation, |
| 19 | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| 20 | |
| 21 | Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
| 22 | CA 95054 USA or visit www.sun.com if you need additional information or |
| 23 | have any questions. |
| 24 | --> |
| 25 | |
| 26 | <html> |
| 27 | <head> |
| 28 | <style> |
| 29 | .key { color: red; font-weight: bold } |
| 30 | </style> |
| 31 | <title> |
| 32 | Object Query Language (OQL) |
| 33 | </title> |
| 34 | </head> |
| 35 | <body> |
| 36 | <h1>Object Query Language (OQL)</h1> |
| 37 | |
| 38 | <p> |
| 39 | OQL is SQL-like query language to query Java heap. OQL allows to filter/select information |
| 40 | wanted from Java heap. While pre-defined queries such as "show all instances of class X" |
| 41 | are already supported by HAT, OQL adds more flexibility. OQL is based on JavaScript expression |
| 42 | language. |
| 43 | </p> |
| 44 | |
| 45 | <p> |
| 46 | OQL query is of the form |
| 47 | |
| 48 | <pre> |
| 49 | <code> |
| 50 | <span class="key">select</span> <JavaScript expression to select> |
| 51 | [ <span class="key">from</span> [<span class="key">instanceof</span>] <class name> <identifier> |
| 52 | [ <span class="key">where</span> <JavaScript boolean expression to filter> ] ] |
| 53 | </code> |
| 54 | </pre> |
| 55 | where class name is fully qualified Java class name (example: java.net.URL) or array class name. |
| 56 | [C is char array name, [Ljava.io.File; is name of java.io.File[] and so on. |
| 57 | Note that fully qualified class name does not always uniquely identify a |
| 58 | Java class at runtime. There may be more than one Java class with the same |
| 59 | name but loaded by different loaders. So, class name is permitted to be |
| 60 | id string of the class object. |
| 61 | |
| 62 | If <span class="key">instanceof</span> keyword is used, subtype objects are selected. If this |
| 63 | keyword is not specified, only the instances of exact class specified are selected. Both |
| 64 | <span class="key">from</span> and <span class="key">where</span> clauses are optional. |
| 65 | </p> |
| 66 | |
| 67 | |
| 68 | <p> |
| 69 | In <span class="key">select</span> and (optional) <span class="key">where</span> clauses, the expression |
| 70 | used in JavaScript expression. Java heap objects are wrapped as convenient script objects so that |
| 71 | fields may be accessed in natural syntax. For example, Java fields can be accessed with obj.field_name |
| 72 | syntax and array elements can be accessed with array[index] syntax. Each Java object selected is |
| 73 | bound to a JavaScript variable of the identifier name specified in <span class="key">from</span> clause. |
| 74 | </p> |
| 75 | |
| 76 | <h2>OQL Examples</h2> |
| 77 | |
| 78 | <ul> |
| 79 | <li>select all Strings of length 100 or more |
| 80 | <pre> |
| 81 | <code> |
| 82 | select s from java.lang.String s where s.count >= 100 |
| 83 | </code> |
| 84 | </pre> |
| 85 | <li>select all int arrays of length 256 or more |
| 86 | <pre> |
| 87 | <code> |
| 88 | select a from [I a where a.length >= 256 |
| 89 | </code> |
| 90 | </pre> |
| 91 | <li>show content of Strings that match a regular expression |
| 92 | <pre> |
| 93 | <code> |
| 94 | select s.value.toString() from java.lang.String s |
| 95 | where /java/(s.value.toString()) |
| 96 | </code> |
| 97 | </pre> |
| 98 | <li>show path value of all File objects |
| 99 | <pre> |
| 100 | <code</b> |
| 101 | select file.path.value.toString() from java.io.File file |
| 102 | </code> |
| 103 | </pre> |
| 104 | <li>show names of all ClassLoader classes |
| 105 | <pre> |
| 106 | <code> |
| 107 | select <a href="#classof">classof</a>(cl).name |
| 108 | from instanceof java.lang.ClassLoader cl |
| 109 | </code> |
| 110 | </pre> |
| 111 | <li>show instances of the Class identified by given id string |
| 112 | <pre> |
| 113 | <code> |
| 114 | select o from instanceof 0xd404b198 o |
| 115 | </code> |
| 116 | </pre> |
| 117 | Note that 0xd404b198 is id of a Class (in a session). This is found by |
| 118 | looking at the id shown in that class's page. |
| 119 | </ul> |
| 120 | |
| 121 | <h2>OQL built-in objects, functions</h2> |
| 122 | |
| 123 | <h3>heap object</h3> |
| 124 | |
| 125 | The <b>heap</b> built-in object supports the following methods: |
| 126 | |
| 127 | <ul> |
| 128 | <li><b>heap.forEachClass</b> -- calls a callback function for each Java Class |
| 129 | <pre> |
| 130 | <code> |
| 131 | heap.forEachClass(callback); |
| 132 | </code> |
| 133 | </pre> |
| 134 | <li><b>heap.forEachObject</b> -- calls a callback function for each Java object |
| 135 | <pre> |
| 136 | <code> |
| 137 | heap.forEachObject(callback, clazz, includeSubtypes); |
| 138 | </code> |
| 139 | </pre> |
| 140 | <code>clazz</code> is the class whose instances are selected. If not specified, defaults to java.lang.Object. <code>includeSubtypes</code> is a boolean flag |
| 141 | that specifies whether to include subtype instances or not. Default value of |
| 142 | this flag is true. |
| 143 | <a name="findClass"></a> |
| 144 | <li><b>heap.findClass</b> -- finds Java Class of given name |
| 145 | <pre> |
| 146 | <code> |
| 147 | heap.findClass(className); |
| 148 | </code> |
| 149 | </pre> |
| 150 | where <code>className</code> is name of the class to find. The resulting Class |
| 151 | object has following properties: |
| 152 | <ul> |
| 153 | <li>name - name of the class. |
| 154 | <li>superclass - Class object for super class (or null if java.lang.Object). |
| 155 | <li>statics - name, value pairs for static fields of the Class. |
| 156 | <li>fields - array of field objects. field object has name, signature |
| 157 | properties. |
| 158 | <li>loader - ClassLoader object that loaded this class. |
| 159 | <li>signers - signers that signed this class. |
| 160 | <li>protectionDomain - protection domain to which this class belongs. |
| 161 | </ul> |
| 162 | Class objects have the following methods: |
| 163 | <ul> |
| 164 | <li>isSubclassOf - tests whether given class is direct or indirect |
| 165 | subclass of this class or not. |
| 166 | <li>isSuperclassOf - tests whether given Class is direct or indirect |
| 167 | superclass of this class or not. |
| 168 | <li>subclasses - returns array of direct and indirect subclasses. |
| 169 | <li>superclasses - returns array of direct and indirect superclasses. |
| 170 | </ul> |
| 171 | <a name="findObject"></a> |
| 172 | <li><b>heap.findObject</b> -- finds object from given object id |
| 173 | <pre> |
| 174 | <code> |
| 175 | heap.findObject(stringIdOfObject); |
| 176 | </code> |
| 177 | </pre> |
| 178 | <a name="classes"></a> |
| 179 | <li><b>heap.classes</b> -- returns an enumeration of all Java classes |
| 180 | <a name="objects"></a> |
| 181 | <li><b>heap.objects</b> -- returns an enumeration of Java objects |
| 182 | <pre> |
| 183 | <code> |
| 184 | heap.objects(clazz, [includeSubtypes], [filter]) |
| 185 | </code> |
| 186 | </pre> |
| 187 | <code>clazz</code> is the class whose instances are selected. If not specified, defaults to java.lang.Object. <code>includeSubtypes</code> is a boolean flag |
| 188 | that specifies whether to include subtype instances or not. Default value of |
| 189 | this flag is true. This method accepts an optional filter expression to filter |
| 190 | the result set of objects. |
| 191 | <a name="finalizables"></a> |
| 192 | <li><b>heap.finalizables</b> -- returns an enumeration of Java objects that are |
| 193 | pending to be finalized. |
| 194 | <li><b>heap.livepaths</b> -- return an array of paths by which a given object |
| 195 | is alive. This method accepts optional second parameter that is a boolean |
| 196 | flag. This flag tells whether to include paths with weak reference(s) or not. |
| 197 | By default, paths with weak reference(s) are not included. |
| 198 | <pre> |
| 199 | <code> |
| 200 | select heap.livepaths(s) from java.lang.String s |
| 201 | </code> |
| 202 | </pre> |
| 203 | Each element of this array itself is another array. The later array is |
| 204 | contains an objects that are in the 'reference chain' of the path. |
| 205 | <li><b>heap.roots</b> -- returns an Enumeration of Roots of the heap. |
| 206 | <a name="rootobj"></a> |
| 207 | Each Root object has the following properties: |
| 208 | <ul> |
| 209 | <li>id - String id of the object that is referred by this root |
| 210 | <li>type - descriptive type of Root (JNI Global, JNI Local, Java Static etc) |
| 211 | <li>description - String description of the Root |
| 212 | <li>referrer - Thread Object or Class object that is responsible for this root or null |
| 213 | </ul> |
| 214 | </ul> |
| 215 | |
| 216 | Examples: |
| 217 | <ul> |
| 218 | <li>access static field 'props' of class java.lang.System |
| 219 | <pre> |
| 220 | <code> |
| 221 | select heap.findClass("java.lang.System").statics.props |
| 222 | select heap.findClass("java.lang.System").props |
| 223 | </code> |
| 224 | </pre> |
| 225 | <li>get number of fields of java.lang.String class |
| 226 | <pre> |
| 227 | <code> |
| 228 | select heap.findClass("java.lang.String").fields.length |
| 229 | </code> |
| 230 | </pre> |
| 231 | <li> find the object whose object id is given |
| 232 | <pre> |
| 233 | <code> |
| 234 | select heap.findObject("0xf3800b58") |
| 235 | </code> |
| 236 | </pre> |
| 237 | <li>select all classes that have name pattern java.net.* |
| 238 | <pre> |
| 239 | <code> |
| 240 | select <a href="#filter">filter</a>(heap.classes(), "/java.net./(it.name)") |
| 241 | </code> |
| 242 | </pre> |
| 243 | </ul> |
| 244 | |
| 245 | <h3>functions on individual objects</h3> |
| 246 | |
| 247 | <ul> |
| 248 | <li><a href="#allocTrace">allocTrace(jobject)</a> |
| 249 | <li><a href="#classof">classof(jobject)</a> |
| 250 | <li><a href="#forEachReferrer">forEachReferrer(callback, jobject)</a> |
| 251 | <li><a href="#identical">identical(o1, o2)</a> |
| 252 | <li><a href="#objectid">objectid(jobject)</a> |
| 253 | <li><a href="#reachables">reachables(jobject, excludedFields)</a> |
| 254 | <li><a href="#referrers">referrers(jobject)</a> |
| 255 | <li><a href="#referees">referees(jobject)</a> |
| 256 | <li><a href="#refers">refers(jobject)</a> |
| 257 | <li><a href="#root">root(jobject)</a> |
| 258 | <li><a href="#sizeof">sizeof(jobject)</a> |
| 259 | <li><a href="#toHtml">toHtml(obj)</a> |
| 260 | </ul> |
| 261 | |
| 262 | <a name="allocTrace"></a> |
| 263 | <h4>allocTrace function</h4> |
| 264 | |
| 265 | This returns allocation site trace of a given Java object if available. |
| 266 | allocTrace returns array of frame objects. Each frame object has the following |
| 267 | properties: |
| 268 | <ul> |
| 269 | <li>className - name of the Java class whose method is running in the frame. |
| 270 | <li>methodName - name of the Java method running in the frame. |
| 271 | <li>methodSignature - signature of the Java method running in the frame. |
| 272 | <li>sourceFileName - name of source file of the Java class running in the frame. |
| 273 | <li>lineNumber - source line number within the method. |
| 274 | </ul> |
| 275 | |
| 276 | <a name="classof"></a> |
| 277 | <h4>classof function</h4> |
| 278 | |
| 279 | Returns Class object of a given Java Object. The result object supports the |
| 280 | following properties: |
| 281 | <ul> |
| 282 | <li>name - name of the class. |
| 283 | <li>superclass - Class object for super class (or null if java.lang.Object). |
| 284 | <li>statics - name, value pairs for static fields of the Class. |
| 285 | <li>fields - array of field objects. Field objects have name, signature |
| 286 | properties. |
| 287 | <li>loader - ClassLoader object that loaded this class. |
| 288 | <li>signers - signers that signed this class. |
| 289 | <li>protectionDomain - protection domain to which this class belongs. |
| 290 | </ul> |
| 291 | Class objects have the following methods: |
| 292 | <ul> |
| 293 | <li>isSubclassOf - tests whether given class is direct or indirect |
| 294 | subclass of this class or not. |
| 295 | <li>isSuperclassOf - tests whether given Class is direct or indirect |
| 296 | superclass of this class or not. |
| 297 | <li>subclasses - returns array of direct and indirect subclasses. |
| 298 | <li>superclasses - returns array of direct and indirect superclasses. |
| 299 | </ul> |
| 300 | |
| 301 | Examples: |
| 302 | <ul> |
| 303 | <li>show class name of each Reference type object |
| 304 | <pre> |
| 305 | <code> |
| 306 | select classof(o).name from instanceof java.lang.ref.Reference o |
| 307 | </code> |
| 308 | <li>show all subclasses of java.io.InputStream |
| 309 | <pre> |
| 310 | <code> |
| 311 | select heap.findClass("java.io.InputStream").subclasses() |
| 312 | </code> |
| 313 | <li>show all superclasses of java.io.BufferedInputStream |
| 314 | <pre> |
| 315 | <code> |
| 316 | select heap.findClass("java.io.BufferedInputStream").superclasses() |
| 317 | </code> |
| 318 | </pre> |
| 319 | </ul> |
| 320 | |
| 321 | <a name="forEachReferrer"></a> |
| 322 | <h4>forEachReferrer function</h4> |
| 323 | |
| 324 | calls a callback function for each referrer of a given Java object. |
| 325 | |
| 326 | <a name="identical"></a> |
| 327 | <h4>identical function</h4> |
| 328 | <p> |
| 329 | Returns whether two given Java objects are identical or not. |
| 330 | </p> |
| 331 | Example: |
| 332 | <pre> |
| 333 | <code> |
| 334 | select identical(heap.findClass("Foo").statics.bar, heap.findClass("AnotherClass").statics.bar) |
| 335 | </code> |
| 336 | </pre> |
| 337 | |
| 338 | <a name="objectid"></a> |
| 339 | <h4>objectid function</h4> |
| 340 | |
| 341 | <p> |
| 342 | Returns String id of a given Java object. This id can be passed to |
| 343 | <a href="#findObject">heap.findObject</a> and may also be used to compare |
| 344 | objects for identity. |
| 345 | </p> |
| 346 | Example: |
| 347 | <pre> |
| 348 | <code> |
| 349 | select objectid(o) from java.lang.Object o |
| 350 | </code> |
| 351 | </pre> |
| 352 | |
| 353 | <a name="reachables"></a> |
| 354 | <h4>reachables function</h4> |
| 355 | <p> |
| 356 | Returns an array of Java objects that are transitively referred from the |
| 357 | given Java object. Optionally accepts a second parameter that is comma |
| 358 | separated field names to be excluded from reachability computation. |
| 359 | Fields are written in class_name.field_name pattern. |
| 360 | </p> |
| 361 | Examples: |
| 362 | <ul> |
| 363 | <li>print all reachable objects from each Properties instance. |
| 364 | <pre> |
| 365 | <code> |
| 366 | select reachables(p) from java.util.Properties p |
| 367 | </code> |
| 368 | </pre> |
| 369 | <li>print all reachables from each java.net.URL but omit the objects reachable |
| 370 | via the fields specified. |
| 371 | <pre> |
| 372 | <code> |
| 373 | select reachables(u, 'java.net.URL.handler') from java.net.URL u |
| 374 | </code> |
| 375 | </pre> |
| 376 | </ul> |
| 377 | |
| 378 | <a name="referrers"></a> |
| 379 | <h4>referrers function</h4> |
| 380 | <p> |
| 381 | Returns an enumeration of Java objects that hold reference to a given Java |
| 382 | object. |
| 383 | </p> |
| 384 | Examples: |
| 385 | <ul> |
| 386 | <li> print number of referrers for each java.lang.Object instance |
| 387 | <pre> |
| 388 | <code> |
| 389 | select count(referrers(o)) from java.lang.Object o |
| 390 | </code> |
| 391 | </pre> |
| 392 | <li>print referrers for each java.io.File object |
| 393 | <pre> |
| 394 | <code> |
| 395 | select referrers(f) from java.io.File f |
| 396 | </code> |
| 397 | </pre> |
| 398 | <li>print URL objects only if referred by 2 or more |
| 399 | <pre> |
| 400 | <code> |
| 401 | select u from java.net.URL u where count(referrers(u)) > 2 |
| 402 | </code> |
| 403 | </pre> |
| 404 | </ul> |
| 405 | |
| 406 | <a name="referees"></a> |
| 407 | <h4>referees function</h4> |
| 408 | <p> |
| 409 | Returns an array of Java objects to which the given Java |
| 410 | object directly refers to. |
| 411 | </p> |
| 412 | Example: to print all static reference fields of java.io.File class |
| 413 | <pre> |
| 414 | <code> |
| 415 | select referees(<a href="#findClass">heap.findClass</a>("java.io.File")) |
| 416 | </code> |
| 417 | </pre> |
| 418 | |
| 419 | <a name="refers"></a> |
| 420 | <h4>refers function</h4> |
| 421 | <p> |
| 422 | Returns whether first Java object refers to second Java object or not. |
| 423 | </p> |
| 424 | |
| 425 | <a name="root"></a> |
| 426 | <h4>root function</h4> |
| 427 | <p> |
| 428 | If given object is a member of root set of objects, this function returns |
| 429 | a descriptive <a href="#rootobj">Root object</a> describing why it is so. |
| 430 | If given object is not a root, then this function returns null. |
| 431 | </p> |
| 432 | |
| 433 | <a name="sizeof"></a> |
| 434 | <h4>sizeof function</h4> |
| 435 | |
| 436 | Returns size of the given Java object in bytes |
| 437 | Example: |
| 438 | <pre> |
| 439 | <code> |
| 440 | select sizeof(o) from [I o |
| 441 | </code> |
| 442 | </pre> |
| 443 | |
| 444 | <a name="toHtml"></a> |
| 445 | <h4>toHtml function</h4> |
| 446 | |
| 447 | Returns HTML string for the given Java object. Note that this is called |
| 448 | automatically for objects selected by select expression. But, it may be useful |
| 449 | to print more complex output. |
| 450 | |
| 451 | Example: print hyperlink in bold font weight |
| 452 | <pre> |
| 453 | <code> |
| 454 | select "<b>" + toHtml(o) + "</b>" from java.lang.Object o |
| 455 | </code> |
| 456 | </pre> |
| 457 | |
| 458 | <h3>Selecting multiple values</h3> |
| 459 | <p> |
| 460 | Multiple values can be selected using JavaScript object literals or arrays. |
| 461 | </p> |
| 462 | |
| 463 | Example: show name and thread for each thread object |
| 464 | <pre> |
| 465 | <code> |
| 466 | select { name: t.name? t.name.toString() : "null", thread: t } |
| 467 | from instanceof java.lang.Thread t |
| 468 | </code> |
| 469 | </pre> |
| 470 | |
| 471 | <h3>array/iterator/enumeration manipulation functions</h3> |
| 472 | |
| 473 | <p> |
| 474 | These functions accept an array/iterator/enumeration and an |
| 475 | expression string [or a callback function] as input. These functions iterate |
| 476 | the array/iterator/enumeration and apply the expression (or function) on |
| 477 | each element. Note that JavaScript objects are associative arrays. So, |
| 478 | these functions may also be used with arbitrary JavaScript objects. |
| 479 | </p> |
| 480 | |
| 481 | <ul> |
| 482 | <li><a href="#concat">concat(array1/enumeration1, array2/enumeration2)</a> |
| 483 | <li><a href="#contains">contains(array/enumeration, expression)</a> |
| 484 | <li><a href="#count">count(array/enumeration, expression)</a> |
| 485 | <li><a href="#filter">filter(array/enumeration, expression)</a> |
| 486 | <li><a href="#length">length(array/enumeration)</a> |
| 487 | <li><a href="#map">map(array/enumeration, expression)</a> |
| 488 | <li><a href="#max">max(array/enumeration, [expression])</a> |
| 489 | <li><a href="#min">min(array/enumeration, [expression])</a> |
| 490 | <li><a href="#sort">sort(array/enumeration, [expression])</a> |
| 491 | <li><a href="#sum">sum(array/enumeration, [expression])</a> |
| 492 | <li><a href="#toArray">toArray(array/enumeration)</a> |
| 493 | <li><a href="#unique">unique(array/enumeration, [expression])</a> |
| 494 | </ul> |
| 495 | |
| 496 | <a name="concat"></a> |
| 497 | <h4>concat function</h4> |
| 498 | <p> |
| 499 | Concatenates two arrays or enumerations (i.e., returns composite |
| 500 | enumeration). |
| 501 | </p> |
| 502 | |
| 503 | <a name="contains"></a> |
| 504 | <h4>contains function</h4> |
| 505 | <p> |
| 506 | Returns whether the given array/enumeration contains an element |
| 507 | the given boolean expression specified in code. The code evaluated |
| 508 | can refer to the following built-in variables. |
| 509 | </p> |
| 510 | <ul> |
| 511 | <li>it -> currently visited element |
| 512 | <li>index -> index of the current element |
| 513 | <li>array -> array/enumeration that is being iterated |
| 514 | </ul> |
| 515 | Example: select all Properties objects that are referred by |
| 516 | some static field some class. |
| 517 | <pre> |
| 518 | <code> |
| 519 | select p from java.util.Properties p |
| 520 | where contains(<a href="#referrers">referrers</a>(p), "<a href="#classof">classof</a>(it).name == 'java.lang.Class'") |
| 521 | </code> |
| 522 | </pre> |
| 523 | |
| 524 | <a name="count"></a> |
| 525 | <h4>count function</h4> |
| 526 | <p> |
| 527 | count function returns the count of elements of the input array/enumeration |
| 528 | that satisfy the given boolean expression. The boolean expression code can |
| 529 | refer to the following built-in variables. |
| 530 | </p> |
| 531 | <ul> |
| 532 | <li>it -> currently visited element |
| 533 | <li>index -> index of the current element |
| 534 | <li>array -> array/enumeration that is being iterated |
| 535 | </ul> |
| 536 | Example: print number of classes that have specific name pattern |
| 537 | <pre> |
| 538 | <code> |
| 539 | select count(<a href="#classes">heap.classes()</a>, "/java.io./(it.name)") |
| 540 | </code> |
| 541 | </pre> |
| 542 | |
| 543 | <a name="filter"></a> |
| 544 | <h4>filter function</h4> |
| 545 | <p> |
| 546 | filter function returns an array/enumeration that contains elements |
| 547 | of the input array/enumeration that satisfy the given boolean |
| 548 | expression. The boolean expression code can refer to the following built-in |
| 549 | variables. |
| 550 | </p> |
| 551 | <ul> |
| 552 | <li>it -> currently visited element |
| 553 | <li>index -> index of the current element |
| 554 | <li>array -> array/enumeration that is being iterated |
| 555 | <li>result -> result array/enumeration |
| 556 | </ul> |
| 557 | Examples: |
| 558 | <ul> |
| 559 | <li>show all classes that have java.io.* name pattern |
| 560 | <pre> |
| 561 | <code> |
| 562 | select filter(<a href="#classes">heap.classes</a>(), "/java.io./(it.name)") |
| 563 | </code> |
| 564 | </pre> |
| 565 | <li> show all referrers of URL object where the referrer is not from |
| 566 | java.net package |
| 567 | <pre> |
| 568 | <code> |
| 569 | select filter(<a href="#referrers">referrers</a>(u), "! /java.net./(<a href="#classof">classof</a>(it).name)") |
| 570 | from java.net.URL u |
| 571 | </code> |
| 572 | </pre> |
| 573 | </ul> |
| 574 | |
| 575 | <a name="length"></a> |
| 576 | <h4>length function</h4> |
| 577 | <p> |
| 578 | length function returns number of elements of an array/enumeration. |
| 579 | </p> |
| 580 | |
| 581 | <a name="map"></a> |
| 582 | <h4>map function</h4> |
| 583 | <p> |
| 584 | Transforms the given array/enumeration by evaluating given code |
| 585 | on each element. The code evaluated can refer to the following built-in |
| 586 | variables. |
| 587 | </p> |
| 588 | <ul> |
| 589 | <li>it -> currently visited element |
| 590 | <li>index -> index of the current element |
| 591 | <li>array -> array/enumeration that is being iterated |
| 592 | <li>result -> result array/enumeration |
| 593 | </ul> |
| 594 | <p> |
| 595 | map function returns an array/enumeration of values created by repeatedly |
| 596 | calling code on each element of input array/enumeration. |
| 597 | </p> |
| 598 | Example: show all static fields of java.io.File with name and value |
| 599 | <pre> |
| 600 | <code> |
| 601 | select map(<a href="#findClass">heap.findClass</a>("java.io.File").statics, "index + '=' + <a href="#toHtml">toHtml</a>(it)") |
| 602 | </code> |
| 603 | </pre> |
| 604 | |
| 605 | <a name="max"></a> |
| 606 | <h4>max function</h4> |
| 607 | <p> |
| 608 | returns the maximum element of the given array/enumeration. |
| 609 | Optionally accepts code expression to compare elements of the array. |
| 610 | By default numerical comparison is used. The comparison expression can |
| 611 | use the following built-in variables: |
| 612 | </p> |
| 613 | <ul> |
| 614 | <li>lhs -> left side element for comparison |
| 615 | <li>rhs -> right side element for comparison |
| 616 | </ul> |
| 617 | Examples: |
| 618 | <ul> |
| 619 | <li>find the maximum length of any String instance |
| 620 | <pre> |
| 621 | <code> |
| 622 | select max(map(heap.objects('java.lang.String', false), 'it.count')) |
| 623 | </code> |
| 624 | </pre> |
| 625 | <li>find string instance that has the maximum length |
| 626 | <pre> |
| 627 | <code> |
| 628 | select max(heap.objects('java.lang.String'), 'lhs.count > rhs.count') |
| 629 | </code> |
| 630 | </pre> |
| 631 | </ul> |
| 632 | |
| 633 | <a name="min"></a> |
| 634 | <h4>min function</h4> |
| 635 | <p> |
| 636 | returns the minimum element of the given array/enumeration. Optionally |
| 637 | accepts code expression to compare elements of the array. By default numerical |
| 638 | comparison is used. The comparison expression can use the following built-in |
| 639 | variables: |
| 640 | </p> |
| 641 | <ul> |
| 642 | <li>lhs -> left side element for comparison |
| 643 | <li>rhs -> right side element for comparison |
| 644 | </ul> |
| 645 | Examples: |
| 646 | <ul> |
| 647 | <li>find the minimum size of any Vector instance |
| 648 | <pre> |
| 649 | <code> |
| 650 | select min(map(heap.objects('java.util.Vector', false), 'it.elementData.length')) |
| 651 | </code> |
| 652 | </pre> |
| 653 | <li>find Vector instance that has the maximum length |
| 654 | <pre> |
| 655 | <code> |
| 656 | select min(heap.objects('java.util.Vector'), 'lhs.elementData.length < rhs.elementData.length') |
| 657 | </code> |
| 658 | </ul> |
| 659 | |
| 660 | <a name="sort"></a> |
| 661 | <h4>sort function</h4> |
| 662 | <p> |
| 663 | sorts given array/enumeration. Optionally accepts code expression to |
| 664 | compare elements of the array. By default numerical comparison is used. |
| 665 | The comparison expression can use the following built-in variables: |
| 666 | </p> |
| 667 | <ul> |
| 668 | <li>lhs -> left side element for comparison |
| 669 | <li>rhs -> right side element for comparison |
| 670 | </ul> |
| 671 | Examples: |
| 672 | <ul> |
| 673 | <li> print all char[] objects in the order of size. |
| 674 | <pre> |
| 675 | <code> |
| 676 | select sort(<a href="#objects">heap.objects</a>('[C'), '<a href="#sizeof">sizeof</a>(lhs) - sizeof(rhs)') |
| 677 | </code> |
| 678 | </pre> |
| 679 | <li> print all char[] objects in the order of size but print |
| 680 | size as well. |
| 681 | <pre> |
| 682 | <code> |
| 683 | select <a href="#map">map</a>(sort(<a href="#objects">heap.objects</a>('[C'), '<a href="#sizeof">sizeof</a>(lhs) - sizeof(rhs)'), '{ size: sizeof(it), obj: it }') |
| 684 | </code> |
| 685 | </pre> |
| 686 | </ul> |
| 687 | |
| 688 | <a name="sum"></a> |
| 689 | <h4>sum function</h4> |
| 690 | <p> |
| 691 | This function returns the sum of all the elements of the given input array or |
| 692 | enumeration. Optionally, accepts an expression as second param. This is used |
| 693 | to map the input elements before summing those. |
| 694 | </p> |
| 695 | Example: return sum of sizes of the reachable objects from each Properties object |
| 696 | <pre> |
| 697 | <code> |
| 698 | select sum(<a href="#map">map</a>(<a href="#reachables">reachables</a>(p), '<a href="#sizeof">sizeof</a>(it)')) |
| 699 | from java.util.Properties p |
| 700 | |
| 701 | // or omit the map as in ... |
| 702 | select sum(<a href="#reachables">reachables</a>(p), '<a href="#sizeof">sizeof</a>(it)') |
| 703 | from java.util.Properties p |
| 704 | </code> |
| 705 | </code> |
| 706 | </pre> |
| 707 | |
| 708 | <a name="toArray"></a> |
| 709 | <h4>toArray function</h4> |
| 710 | <p> |
| 711 | This function returns an array that contains elements of the input |
| 712 | array/enumeration. |
| 713 | </p> |
| 714 | |
| 715 | <a name="unique"></a> |
| 716 | <h4>unique function</h4> |
| 717 | <p> |
| 718 | This function returns an array/enumeration containing unique elements of the |
| 719 | given input array/enumeration |
| 720 | </p> |
| 721 | Example: select unique char[] instances referenced from Strings. Note that |
| 722 | more than one String instance can share the same char[] for the content. |
| 723 | <pre> |
| 724 | <code> |
| 725 | // number of unique char[] instances referenced from any String |
| 726 | select count(unique(map(heap.objects('java.lang.String'), 'it.value'))) |
| 727 | |
| 728 | // total number of Strings |
| 729 | select count(heap.objects('java.lang.String')) |
| 730 | </code> |
| 731 | </pre> |
| 732 | |
| 733 | <h3>More complex examples</h3> |
| 734 | |
| 735 | <h4>Print histogram of each class loader and number of classes loaded by it</h4> |
| 736 | |
| 737 | <pre> |
| 738 | <code> |
| 739 | select <a href="#map">map</a>(<a href="#sort">sort</a>(map(heap.objects('java.lang.ClassLoader'), |
| 740 | '{ loader: it, count: it.classes.elementCount }'), 'lhs.count < rhs.count'), |
| 741 | 'toHtml(it) + "<br>"') |
| 742 | </code> |
| 743 | </pre> |
| 744 | <p> |
| 745 | The above query uses the fact that, <b>java.lang.ClassLoader</b> has a private |
| 746 | field called <b>classes</b> of type <b>java.util.Vector</b> and Vector has a |
| 747 | private field named <b>elementCount</b> that is number of elements in the |
| 748 | vector. We select multiple values (loader, count) using JavaScript object |
| 749 | literal and map function. We sort the result by count (i.e., number of classes |
| 750 | loaded) using sort function with comparison expression. |
| 751 | </p> |
| 752 | |
| 753 | <h4>Show parent-child chain for each class loader instance</h4> |
| 754 | |
| 755 | <pre> |
| 756 | <code> |
| 757 | select <a href="#map">map</a>(heap.objects('java.lang.ClassLoader'), |
| 758 | function (it) { |
| 759 | var res = ''; |
| 760 | while (it != null) { |
| 761 | res += toHtml(it) + "->"; |
| 762 | it = it.parent; |
| 763 | } |
| 764 | res += "null"; |
| 765 | return res + "<br>"; |
| 766 | }) |
| 767 | </code> |
| 768 | </pre> |
| 769 | <p> |
| 770 | Note that we use <b>parent</b> field of <b>java.lang.ClassLoader</b> class |
| 771 | and walk until parent is null using the callback function to map call. |
| 772 | </p> |
| 773 | |
| 774 | <h4>Printing value of all System properties</h4> |
| 775 | |
| 776 | <pre> |
| 777 | <code> |
| 778 | select <a href="#map">map</a>(<a href="#filter">filter(<a href="#findClass">heap.findClass</a>('java.lang.System').props.table, 'it != null'), |
| 779 | function (it) { |
| 780 | var res = ""; |
| 781 | while (it != null) { |
| 782 | res += it.key.value.toString() + '=' + |
| 783 | it.value.value.toString() + '<br>'; |
| 784 | it = it.next; |
| 785 | } |
| 786 | return res; |
| 787 | }); |
| 788 | </code> |
| 789 | </pre> |
| 790 | <p> |
| 791 | The above query uses the following facts: |
| 792 | <ul> |
| 793 | <li>java.lang.System has static field by name 'props' of type java.util.Properties. |
| 794 | <li>java.util.Properties has field by 'table' of type java.util.Hashtable$Entry |
| 795 | (this field is inherited from java.util.Hashtable). This is the hashtable |
| 796 | buckets array. |
| 797 | <li>java.util.Hashtable$Entry has 'key', 'value' and 'next' fields. Each |
| 798 | entry points the next entry (or null) in the same hashtable bucket. |
| 799 | <li>java.lang.String class has 'value' field of type char[]. |
| 800 | </ul> |
| 801 | <p> |
| 802 | <b>Note that this query (and many other queries) may not be stable - because |
| 803 | private fields of Java platform classes may be modified/removed without any |
| 804 | notification! (implementation detail)</b>. But, using such queries on user |
| 805 | classes may be safe - given that user has the control over the classes. |
| 806 | </p> |
| 807 | |
| 808 | </body> |
| 809 | </html> |