├── .editorconfig ├── .gitignore ├── JMC_Tutorial.pdf ├── LICENSE ├── README.md ├── autorecordings └── README.md ├── docs ├── README.md ├── _config.yml ├── images.go └── images │ ├── arrow.png │ ├── branch-icon-0.png │ ├── branch-icon-1.png │ ├── branch-icon-2.png │ ├── branch-icon-3.png │ ├── eclipse-close-recording-window.png │ ├── eclipse-debug-perspective-terminate.png │ ├── eclipse-import-existing-projects.png │ ├── eclipse-import-tutorial-all-projects.png │ ├── eclipse-java-perspective-button-toggle.png │ ├── eclipse-java-perspective-button.png │ ├── eclipse-java-perspective-console-view.png │ ├── eclipse-java-perspective.png │ ├── eclipse-jmc-add-trigger.png │ ├── eclipse-jmc-analysis-offending-monitor.png │ ├── eclipse-jmc-ancestor-referer.png │ ├── eclipse-jmc-application-outline-view-do-nothing.png │ ├── eclipse-jmc-application-outline-view-hotmethods.png │ ├── eclipse-jmc-automated-recording-analysis-do-nothing.png │ ├── eclipse-jmc-automated-recording-analysis-hotmethods.png │ ├── eclipse-jmc-custom-page-filter-duration-threshold.png │ ├── eclipse-jmc-custom-page-filter-duration.png │ ├── eclipse-jmc-custom-page-view.png │ ├── eclipse-jmc-custom-pages.png │ ├── eclipse-jmc-custom-rule-triggering.png │ ├── eclipse-jmc-garbage-collection.png │ ├── eclipse-jmc-jfr-automated-analysis-exceptions.png │ ├── eclipse-jmc-jfr-exceptions-event-bucket.png │ ├── eclipse-jmc-jfr-exceptions-page.png │ ├── eclipse-jmc-jfr-exceptions-selection-2.png │ ├── eclipse-jmc-jfr-exceptions-selection-zoom-in.png │ ├── eclipse-jmc-jfr-exceptions-selection.png │ ├── eclipse-jmc-jfr-exceptions-stacktrace.png │ ├── eclipse-jmc-jfr-fibonacci-threads-other-event-types.png │ ├── eclipse-jmc-jfr-fibonacci-threads.png │ ├── eclipse-jmc-jfr-javafx-pulse.png │ ├── eclipse-jmc-jfr-javafx.png │ ├── eclipse-jmc-jfr-jdbc.png │ ├── eclipse-jmc-jfr-memory-live-objects.png │ ├── eclipse-jmc-jfr-recording-idle.png │ ├── eclipse-jmc-jfr-weblogic-event-browser.png │ ├── eclipse-jmc-jfr-weblogic-events-matching-selection.png │ ├── eclipse-jmc-jfr-weblogic-servlet-focused-selection.png │ ├── eclipse-jmc-jfr-weblogic-servlet.png │ ├── eclipse-jmc-joverflow.png │ ├── eclipse-jmc-jvm-browser-flight-recorder-node-expanded.png │ ├── eclipse-jmc-latency-before-view-all-threads.png │ ├── eclipse-jmc-latency-fixed-all-threads.png │ ├── eclipse-jmc-latency-fixed.png │ ├── eclipse-jmc-launch-with-workspace-plugins.png │ ├── eclipse-jmc-launch-wizard-jfr.png │ ├── eclipse-jmc-lock-instances-page.png │ ├── eclipse-jmc-log4j-contention-add-filter.png │ ├── eclipse-jmc-log4j-contention-add-grouping.png │ ├── eclipse-jmc-log4j-contention-bug.png │ ├── eclipse-jmc-log4j-contention-combine-filter.png │ ├── eclipse-jmc-log4j-contention-show-search.png │ ├── eclipse-jmc-management-console-blank-chart.png │ ├── eclipse-jmc-management-console-thread-count.png │ ├── eclipse-jmc-management-console.png │ ├── eclipse-jmc-mbean-browser.png │ ├── eclipse-jmc-memory-page.png │ ├── eclipse-jmc-method-profiling-hotmethods.png │ ├── eclipse-jmc-perspective-button-toggle.png │ ├── eclipse-jmc-perspective-jvm-browser.png │ ├── eclipse-jmc-referer-tree.png │ ├── eclipse-jmc-rename-custom-page.png │ ├── eclipse-jmc-request-log-add-column.png │ ├── eclipse-jmc-request-log-context-menu-group-by-ecid.png │ ├── eclipse-jmc-request-log-ecid-grouping.png │ ├── eclipse-jmc-request-log-remove-type-filter.png │ ├── eclipse-jmc-request-log-view.png │ ├── eclipse-jmc-reset-class-histogram.png │ ├── eclipse-jmc-reset-to-default-controls.png │ ├── eclipse-jmc-stacktrace-line-numbers.png │ ├── eclipse-jmc-stacktrace-next-frame-group.png │ ├── eclipse-jmc-stacktrace-tree.png │ ├── eclipse-jmc-start-flight-recording.png │ ├── eclipse-jmc-thread-count-freeze-graph.png │ ├── eclipse-jmc-thread-graph-deadlocked.png │ ├── eclipse-jmc-trigger-alerts.png │ ├── eclipse-plugin-project-export-rule.png │ ├── eclipse-plugin-project-no-ui-contribution.png │ ├── eclipse-plugin-project-simple-jfr-rule.png │ ├── eclipse-plugin-project-window.png │ ├── eclipse-plugin-project-wizard.png │ ├── eclipse-preferences-execution-environments.png │ ├── eclipse-preferences-installed-jres.png │ ├── eclipse-run-configurations-application-idle.png │ ├── eclipse-run-do-nothing-program.png │ ├── eclipse-workspace-projects-loaded.png │ ├── javafx-application-lasers.png │ ├── jmc-logo.png │ ├── jmc-start-screen.png │ ├── jmc-welcome-screen-close.png │ └── jmc-welcome-screen.png └── projects ├── 01_DoNothing ├── .classpath ├── .project ├── .settings │ └── org.eclipse.jdt.core.prefs ├── Launchers │ ├── DoNothing Auto Record.launch │ ├── DoNothing Literally 1.7.launch │ ├── DoNothing Literally.launch │ └── DoNothing.launch ├── donothing.jfr └── src │ └── se │ └── hirt │ └── jmc │ └── tutorial │ └── donothing │ └── DoNothing.java ├── 02_JFR_HotMethods ├── .classpath ├── .project ├── .settings │ └── org.eclipse.jdt.core.prefs ├── Launchers │ ├── HotMethods Auto Record.launch │ └── HotMethods.launch ├── Readme.txt ├── hotmethods_before.jfr ├── hotmethods_fixed.jfr └── src │ └── se │ └── hirt │ └── jmc │ └── tutorial │ └── hotmethods │ ├── HolderOfUniqueValues.java │ ├── HotMethods.java │ ├── WorkEvent.java │ └── Worker.java ├── 03_JFR_Latencies ├── .classpath ├── .project ├── .settings │ └── org.eclipse.jdt.core.prefs ├── Launchers │ ├── Latencies Auto Record.launch │ └── Latencies.launch ├── Readme.txt ├── latency_before.jfr ├── latency_fixed.jfr └── src │ └── se │ └── hirt │ └── jmc │ └── tutorial │ └── latencies │ ├── Latencies.java │ ├── LogEvent.java │ ├── Logger.java │ ├── WorkEvent.java │ └── Worker.java ├── 04_JFR_GC ├── .classpath ├── .project ├── Launchers │ ├── Allocations Auto Record.launch │ └── Allocations.launch ├── Readme.txt ├── allocation_before.jfr ├── allocation_fixed.jfr └── src │ └── se │ └── hirt │ └── jmc │ └── tutorial │ └── gc │ ├── Allocations.java │ ├── Allocator.java │ └── ExampleMapContent.java ├── 05_JFR_MemoryLeak ├── .classpath ├── .project ├── Launchers │ ├── Leak Auto Record.launch │ ├── Leak.launch │ └── MultiLoaderLeak.launch ├── Readme.txt ├── memoryleak_before.jfr ├── memoryleak_fixed.jfr └── src │ └── se │ └── hirt │ └── jmc │ └── tutorial │ └── memleak │ ├── CustomLoader.java │ ├── Leak.java │ └── MultiLoaderLeak.java ├── 06_JFR_WLS ├── .classpath ├── .project ├── jmcwldf.jfc ├── other │ └── medrec_dont_use.jfr └── wldf.jfr ├── 07_JFR_JavaFX ├── .classpath ├── .project ├── .settings │ └── org.eclipse.jdt.core.prefs ├── Launchers │ ├── GUIMark Auto Record.launch │ └── GUIMark.launch ├── guimark.jfc ├── guimark.jfr └── lib │ └── GUIMark2.jar ├── 08_JFR_Exceptions ├── .classpath ├── .project ├── Launchers │ ├── ExceptionThrower Auto Record.launch │ └── ExceptionThrower.launch ├── Readme.txt ├── exceptions.jfc ├── exceptions.jfr └── src │ └── se │ └── hirt │ └── jmc │ └── tutorial │ └── exceptions │ ├── ExceptionThrower.java │ ├── ExceptionThrowerException.java │ └── ScaryException.java ├── 09_JFR_CustomEvents ├── .project └── fibonacci.jfr ├── 12_Console_LoadAndDeadlock ├── .classpath ├── .project ├── Launchers │ ├── LoadAndDeadlock Auto Record.launch │ ├── LoadAndDeadlock Continuous Example.launch │ ├── LoadAndDeadlock Dump on Exit.launch │ ├── LoadAndDeadlock Dynamic Enablement.launch │ ├── LoadAndDeadlock NMT.launch │ ├── LoadAndDeadlock Remote Access.launch │ └── LoadAndDeadlock.launch ├── Readme.txt └── src │ └── se │ └── hirt │ └── jmc │ └── tutorial │ └── console │ └── LoadAndDeadlock.java ├── 13_JOverflow ├── .project ├── eclipse.hprof └── jmc41dump.hprof ├── Logs ├── .project └── log.txt └── Recordings └── .project /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | trim_trailing_whitespace = true 7 | insert_final_newline = true 8 | 9 | [*.{md,txt}] 10 | indent_style = space 11 | indent_size = 4 12 | trim_trailing_whitespace = false 13 | max_line_length = 92 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.gradle/ 2 | bin/ 3 | build/ 4 | *.bak 5 | *.class 6 | .DS_Store -------------------------------------------------------------------------------- /JMC_Tutorial.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/JMC_Tutorial.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JDK Mission Control Tutorial 2 | 3 | This tutorial provides plenty of examples and material to help you learn JDK Mission Control (7+). 4 | 5 | ## Preparations 6 | Since it is not practical to pre-package everything required to run the material here at GitHub, there are some preparations required before starting the Tutorial. 7 | 8 | ### Setting up the JDK 9 | You will need to have a JDK 11 or later to do this tutorial. You can either use the [Oracle JDK](http://java.oracle.com) or any OpenJDK build, for example the one provided by [Oracle](http://jdk.java.net/11/). 10 | 11 | You will need to ensure that `java` for your JDK is on your path, and you should also make sure that your JAVA_HOME variable is set to the parent folder of the `bin` folder containing your `java` binary. 12 | 13 | ### Getting the stand alone version of JMC 14 | There are various binary builds of JMC available. 15 | See the JMC github repo for alternatives (any will do): 16 | https://github.com/openjdk/jmc#readme 17 | 18 | ### Setting up Eclipse 19 | The tutorial will be easier to run if you have an Eclipse installed. You will need an Eclipse Oxygen 4.8.0 or later. You will also need to add some VM arguments. 20 | 21 | For example: 22 | 23 | ```ini 24 | -vmargs 25 | -Djdk.attach.allowAttachSelf=true 26 | --add-exports=java.xml/com.sun.org.apache.xerces.internal.parsers=ALL-UNNAMED 27 | --add-exports=jdk.internal.jvmstat/sun.jvmstat.monitor=ALL-UNNAMED 28 | --add-exports=java.management/sun.management=ALL-UNNAMED 29 | --add-exports=java.management/sun.management.counter.perf=ALL-UNNAMED 30 | --add-exports=jdk.management.agent/jdk.internal.agent=ALL-UNNAMED 31 | --add-exports=jdk.attach/sun.tools.attach=ALL-UNNAMED 32 | --add-opens=java.base/java.net=ALL-UNNAMED 33 | --add-opens=jdk.attach/sun.tools.attach=ALL-UNNAMED 34 | ``` 35 | 36 | Depending on your platform you will also need to add one final export. 37 | 38 | If running on Windows, also add: 39 | 40 | ```ini 41 | --add-exports=java.desktop/sun.awt.windows=ALL-UNNAMED 42 | ``` 43 | 44 | If running on Mac OS, also add: 45 | 46 | ```ini 47 | --add-exports=java.desktop/sun.lwawt.macosx=ALL-UNNAMED 48 | ``` 49 | 50 | If running on Linux, also add: 51 | 52 | ```ini 53 | --add-exports=java.desktop/sun.awt.X11=ALL-UNNAMED 54 | ``` 55 | 56 | You may also want to ensure that your newly setup JDK is being used for running Eclipse. This can be enforced by using the -vm option in the eclipse.ini file. Don't forget that the -vmargs option must be last in the file. For example: 57 | 58 | ```ini 59 | -vm 60 | /Library/Java/JavaVirtualMachines/jdk-11.jdk/Contents/Home/bin 61 | -vmargs 62 | -Djdk.attach.allowAttachSelf=true 63 | ... 64 | ``` 65 | 66 | #### Adding the Eclipse plug-ins 67 | 68 | Next you will want to add the JMC plug-ins. You can either get the update site pre-built from AdoptOpenJDK (https://adoptopenjdk.net/jmc), or build it yourself. Install git (if you don't already have it) and run the following command in the folder you wish to clone the JMC source: 69 | 70 | ```bash 71 | git clone https://github.com/openjdk/jmc 72 | ``` 73 | 74 | Follow the instructions in the README.md found in the root of the JMC repository on how to create and access the update sites for Eclipse. 75 | 76 | #### Importing the projects 77 | To import the projects into Eclipse, create a new Workspace and simply import all the projects available in the projects folder. 78 | 79 | ## Running the Tutorial 80 | The [tutorial instructions](https://github.com/thegreystone/jmc-tutorial/tree/master/docs) explain in detail how to run the JMC labs. If running the labs from within Eclipse, first ensure that you have set up an Eclipse properly, added the plug-in version of JMC, and imported the projects. 81 | 82 | ## About 83 | This tutorial is for learning how to use JDK Mission Contol. It is provided under GPLv3 as is. If you find a problem, please open a ticket or feel free to provide a pull request. 84 | -------------------------------------------------------------------------------- /autorecordings/README.md: -------------------------------------------------------------------------------- 1 | # Autorecordings Folder 2 | This is the folder where scripted recordings (or the AUTO launcher initiated recordings) will end up. -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-hacker -------------------------------------------------------------------------------- /docs/images.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "log" 7 | "os" 8 | "os/exec" 9 | "strings" 10 | ) 11 | 12 | type image struct { 13 | idx int 14 | name string 15 | mask bool 16 | } 17 | 18 | func newMaskedImage(idx int, name string) image { 19 | return image{idx, name, true} 20 | } 21 | 22 | func newSimpleImage(idx int, name string) image { 23 | return image{idx, name, false} 24 | } 25 | 26 | var images = []image{ 27 | newMaskedImage(0, "jmc-logo"), 28 | newMaskedImage(2, "jmc-welcome-screen"), 29 | newMaskedImage(4, "jmc-welcome-screen-close"), 30 | newMaskedImage(6, "jmc-start-screen"), 31 | newMaskedImage(8, "eclipse-java-perspective"), 32 | newMaskedImage(10, "eclipse-preferences-installed-jres"), 33 | newMaskedImage(12, "eclipse-preferences-execution-environments"), 34 | newMaskedImage(14, "eclipse-import-existing-projects"), 35 | newMaskedImage(16, "eclipse-import-tutorial-all-projects"), 36 | newMaskedImage(18, "eclipse-workspace-projects-loaded"), 37 | newMaskedImage(20, "eclipse-jmc-perspective-button-toggle"), 38 | newMaskedImage(22, "eclipse-jmc-perspective-jvm-browser"), 39 | newMaskedImage(24, "eclipse-jmc-launch-wizard-jfr"), 40 | newSimpleImage(26, "eclipse-java-perspective-button"), 41 | newMaskedImage(27, "eclipse-java-perspective-button-toggle"), 42 | newMaskedImage(29, "eclipse-run-do-nothing-program"), 43 | newMaskedImage(31, "eclipse-jmc-start-flight-recording"), 44 | newMaskedImage(33, "eclipse-jmc-jvm-browser-flight-recorder-node-expanded"), 45 | newMaskedImage(35, "eclipse-jmc-automated-recording-analysis-do-nothing"), 46 | newMaskedImage(37, "eclipse-jmc-application-outline-view-do-nothing"), 47 | newMaskedImage(39, "eclipse-java-perspective-console-view"), 48 | newMaskedImage(41, "eclipse-debug-perspective-terminate"), 49 | newMaskedImage(43, "eclipse-close-recording-window"), 50 | newMaskedImage(45, "eclipse-jmc-automated-recording-analysis-hotmethods"), 51 | newSimpleImage(47, "eclipse-jmc-application-outline-view-hotmethods"), 52 | newSimpleImage(48, "eclipse-jmc-method-profiling-hotmethods"), 53 | newMaskedImage(49, "branch-icon-0"), 54 | newMaskedImage(51, "branch-icon-1"), 55 | newMaskedImage(53, "branch-icon-2"), 56 | newMaskedImage(55, "branch-icon-3"), 57 | newSimpleImage(57, "eclipse-jmc-stacktrace-next-frame-group"), 58 | newMaskedImage(58, "eclipse-jmc-stacktrace-tree"), 59 | newSimpleImage(60, "eclipse-jmc-stacktrace-line-numbers"), 60 | newMaskedImage(61, "eclipse-jmc-analysis-offending-monitor"), 61 | newSimpleImage(63, "eclipse-jmc-lock-instances-page"), 62 | newSimpleImage(64, "eclipse-jmc-latency-before-view-all-threads"), 63 | newSimpleImage(65, "eclipse-jmc-latency-fixed"), 64 | newSimpleImage(66, "eclipse-jmc-latency-fixed-all-threads"), 65 | newSimpleImage(67, "eclipse-jmc-garbage-collection"), 66 | newSimpleImage(68, "eclipse-jmc-memory-page"), 67 | newMaskedImage(69, "eclipse-jmc-jfr-memory-live-objects"), 68 | newMaskedImage(71, "eclipse-jmc-jfr-jdbc"), 69 | newSimpleImage(73, "eclipse-jmc-jfr-weblogic-servlet"), 70 | newSimpleImage(74, "eclipse-jmc-jfr-weblogic-servlet-focused-selection"), 71 | newMaskedImage(75, "eclipse-jmc-jfr-weblogic-events-matching-selection"), 72 | newSimpleImage(77, "eclipse-jmc-jfr-weblogic-event-browser"), 73 | newMaskedImage(78, "javafx-application-lasers"), 74 | newSimpleImage(80, "eclipse-jmc-jfr-javafx"), 75 | newSimpleImage(81, "eclipse-jmc-jfr-javafx-pulse"), 76 | newMaskedImage(82, "eclipse-jmc-jfr-automated-analysis-exceptions"), 77 | newSimpleImage(84, "eclipse-jmc-jfr-exceptions-page"), 78 | newSimpleImage(85, "eclipse-jmc-jfr-exceptions-stacktrace"), 79 | newSimpleImage(86, "eclipse-jmc-jfr-exceptions-selection"), 80 | newSimpleImage(87, "eclipse-jmc-jfr-exceptions-selection-2"), 81 | newSimpleImage(88, "eclipse-jmc-jfr-exceptions-selection-zoom-in"), 82 | newSimpleImage(89, "eclipse-jmc-jfr-exceptions-event-bucket"), 83 | newSimpleImage(90, "eclipse-jmc-jfr-fibonacci-threads"), 84 | newSimpleImage(91, "eclipse-jmc-jfr-fibonacci-threads-other-event-types"), 85 | newSimpleImage(92, "eclipse-plugin-project-wizard"), 86 | newMaskedImage(93, "eclipse-plugin-project-window"), 87 | newSimpleImage(95, "eclipse-plugin-project-no-ui-contribution"), 88 | newSimpleImage(96, "eclipse-plugin-project-simple-jfr-rule"), 89 | newSimpleImage(97, "eclipse-run-configurations-application-idle"), 90 | newMaskedImage(98, "eclipse-jmc-launch-with-workspace-plugins"), 91 | newSimpleImage(100, "eclipse-jmc-jfr-recording-idle"), 92 | newSimpleImage(101, "eclipse-jmc-custom-rule-triggering"), 93 | newSimpleImage(102, "eclipse-plugin-project-export-rule"), 94 | newMaskedImage(103, "eclipse-jmc-custom-pages"), 95 | newMaskedImage(105, "eclipse-jmc-rename-custom-page"), 96 | newMaskedImage(107, "eclipse-jmc-custom-page-filter-duration"), 97 | newMaskedImage(109, "eclipse-jmc-custom-page-filter-duration-threshold"), 98 | newSimpleImage(111, "eclipse-jmc-custom-page-view"), 99 | newMaskedImage(112, "eclipse-jmc-request-log-ecid-grouping"), 100 | newMaskedImage(114, "eclipse-jmc-request-log-remove-type-filter"), 101 | newMaskedImage(116, "eclipse-jmc-request-log-context-menu-group-by-ecid"), 102 | newMaskedImage(118, "eclipse-jmc-request-log-add-column"), 103 | newSimpleImage(120, "eclipse-jmc-request-log-view"), 104 | newMaskedImage(121, "eclipse-jmc-log4j-contention-show-search"), 105 | newMaskedImage(123, "eclipse-jmc-log4j-contention-add-filter"), 106 | newMaskedImage(125, "eclipse-jmc-log4j-contention-combine-filter"), 107 | newSimpleImage(127, "eclipse-jmc-log4j-contention-bug"), 108 | newSimpleImage(128, "eclipse-jmc-log4j-contention-add-grouping"), 109 | newSimpleImage(129, "eclipse-jmc-management-console"), 110 | newSimpleImage(130, "eclipse-jmc-management-console-blank-chart"), 111 | newSimpleImage(131, "eclipse-jmc-management-console-thread-count"), 112 | newSimpleImage(132, "eclipse-jmc-thread-count-freeze-graph"), 113 | newSimpleImage(133, "eclipse-jmc-mbean-browser"), 114 | newSimpleImage(134, "eclipse-jmc-reset-to-default-controls"), 115 | newSimpleImage(135, "eclipse-jmc-thread-graph-deadlocked"), 116 | newSimpleImage(136, "eclipse-jmc-add-trigger"), 117 | newSimpleImage(137, "eclipse-jmc-trigger-alerts"), 118 | newSimpleImage(138, "eclipse-jmc-joverflow"), 119 | newSimpleImage(139, "arrow"), 120 | newMaskedImage(140, "eclipse-jmc-referer-tree"), 121 | newSimpleImage(142, "eclipse-jmc-reset-class-histogram"), 122 | newSimpleImage(143, "eclipse-jmc-ancestor-referer"), 123 | } 124 | 125 | func (i image) altText() string { 126 | return strings.ReplaceAll(i.name, "-", " ") 127 | } 128 | 129 | type config struct { 130 | srcpdf string 131 | srcdir string 132 | dstdir string 133 | mdfile string 134 | } 135 | 136 | func newConfig(root string) config { 137 | srcpdf := root + "/JMC_Tutorial.pdf" 138 | _, err := os.Stat(srcpdf) 139 | check(err) 140 | var tmpdir, _ = ioutil.TempDir("/tmp", "extracted-images-") 141 | return config{ 142 | srcpdf: srcpdf, 143 | srcdir: tmpdir, 144 | dstdir: root + "/docs/images", 145 | mdfile: root + "/docs/images.md", 146 | } 147 | } 148 | 149 | func (c config) srcpath(i image) string { 150 | return fmt.Sprintf("%s/img-%03d.png", c.srcdir, i.idx) 151 | } 152 | 153 | func (c config) maskpath(i image) string { 154 | return fmt.Sprintf("%s/img-%03d.png", c.srcdir, i.idx+1) 155 | } 156 | 157 | func (c config) dstpath(i image) string { 158 | return fmt.Sprintf("%s/%s.png", c.dstdir, i.name) 159 | } 160 | 161 | func (c config) markdown(i image) (string, string) { 162 | var ref = "![" + i.altText() + "][" + i.name + "]" 163 | var link = "[" + i.name + "]: images/" + i.name + ".png" 164 | return ref, link 165 | } 166 | 167 | func check(err error) { 168 | if err != nil { 169 | log.Fatalf("❌ Image processing failed: %v", err) 170 | } 171 | } 172 | 173 | func main() { 174 | if len(os.Args) != 2 { 175 | log.Fatal("Usage: go run images.go ") 176 | } 177 | rootdir := os.Args[1] 178 | c := newConfig(rootdir) 179 | log.Printf("🤖 extracting and processing images from '%s'", c.srcpdf) 180 | 181 | // brew install poppler 182 | cmd := exec.Command("pdfimages", "-png", c.srcpdf, c.srcdir+"/img") 183 | _, err := cmd.CombinedOutput() 184 | check(err) 185 | files, _ := ioutil.ReadDir(c.srcdir) 186 | log.Printf("🧲 %d images and masks extracted in '%s/'", len(files), c.srcdir) 187 | 188 | os.MkdirAll(c.dstdir, 0755) 189 | for _, img := range images { 190 | var cmd *exec.Cmd 191 | if img.mask { 192 | // brew install imagemagick 193 | cmd = exec.Command("convert", c.srcpath(img), c.maskpath(img), "-alpha", "off", "-compose", "copy-opacity", "-composite", c.dstpath(img)) 194 | } else { 195 | cmd = exec.Command("cp", c.srcpath(img), c.dstpath(img)) 196 | } 197 | stdoutStderr, err := cmd.CombinedOutput() 198 | if err != nil { 199 | fmt.Printf("Command failed: %s\n%s\n", cmd, stdoutStderr) 200 | log.Fatal(err) 201 | } 202 | } 203 | log.Printf("✅ images processed successfully, output in '%s/'", c.dstdir) 204 | 205 | refs, links := []string{}, []string{} 206 | for _, img := range images { 207 | ref, link := c.markdown(img) 208 | refs = append(refs, ref) 209 | links = append(links, link) 210 | } 211 | md := strings.Join(refs, "\n") + "\n\n" + strings.Join(links, "\n") 212 | ioutil.WriteFile(c.mdfile, []byte(md), 0644) 213 | log.Printf("📖 links and references written in '%s'", c.mdfile) 214 | 215 | os.RemoveAll(c.srcdir) 216 | log.Printf("🧹 deleted temporary directory '%s'", c.srcdir) 217 | } 218 | -------------------------------------------------------------------------------- /docs/images/arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/arrow.png -------------------------------------------------------------------------------- /docs/images/branch-icon-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/branch-icon-0.png -------------------------------------------------------------------------------- /docs/images/branch-icon-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/branch-icon-1.png -------------------------------------------------------------------------------- /docs/images/branch-icon-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/branch-icon-2.png -------------------------------------------------------------------------------- /docs/images/branch-icon-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/branch-icon-3.png -------------------------------------------------------------------------------- /docs/images/eclipse-close-recording-window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-close-recording-window.png -------------------------------------------------------------------------------- /docs/images/eclipse-debug-perspective-terminate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-debug-perspective-terminate.png -------------------------------------------------------------------------------- /docs/images/eclipse-import-existing-projects.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-import-existing-projects.png -------------------------------------------------------------------------------- /docs/images/eclipse-import-tutorial-all-projects.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-import-tutorial-all-projects.png -------------------------------------------------------------------------------- /docs/images/eclipse-java-perspective-button-toggle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-java-perspective-button-toggle.png -------------------------------------------------------------------------------- /docs/images/eclipse-java-perspective-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-java-perspective-button.png -------------------------------------------------------------------------------- /docs/images/eclipse-java-perspective-console-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-java-perspective-console-view.png -------------------------------------------------------------------------------- /docs/images/eclipse-java-perspective.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-java-perspective.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-add-trigger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-add-trigger.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-analysis-offending-monitor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-analysis-offending-monitor.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-ancestor-referer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-ancestor-referer.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-application-outline-view-do-nothing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-application-outline-view-do-nothing.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-application-outline-view-hotmethods.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-application-outline-view-hotmethods.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-automated-recording-analysis-do-nothing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-automated-recording-analysis-do-nothing.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-automated-recording-analysis-hotmethods.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-automated-recording-analysis-hotmethods.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-custom-page-filter-duration-threshold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-custom-page-filter-duration-threshold.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-custom-page-filter-duration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-custom-page-filter-duration.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-custom-page-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-custom-page-view.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-custom-pages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-custom-pages.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-custom-rule-triggering.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-custom-rule-triggering.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-garbage-collection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-garbage-collection.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-jfr-automated-analysis-exceptions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-jfr-automated-analysis-exceptions.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-jfr-exceptions-event-bucket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-jfr-exceptions-event-bucket.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-jfr-exceptions-page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-jfr-exceptions-page.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-jfr-exceptions-selection-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-jfr-exceptions-selection-2.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-jfr-exceptions-selection-zoom-in.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-jfr-exceptions-selection-zoom-in.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-jfr-exceptions-selection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-jfr-exceptions-selection.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-jfr-exceptions-stacktrace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-jfr-exceptions-stacktrace.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-jfr-fibonacci-threads-other-event-types.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-jfr-fibonacci-threads-other-event-types.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-jfr-fibonacci-threads.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-jfr-fibonacci-threads.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-jfr-javafx-pulse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-jfr-javafx-pulse.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-jfr-javafx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-jfr-javafx.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-jfr-jdbc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-jfr-jdbc.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-jfr-memory-live-objects.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-jfr-memory-live-objects.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-jfr-recording-idle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-jfr-recording-idle.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-jfr-weblogic-event-browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-jfr-weblogic-event-browser.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-jfr-weblogic-events-matching-selection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-jfr-weblogic-events-matching-selection.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-jfr-weblogic-servlet-focused-selection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-jfr-weblogic-servlet-focused-selection.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-jfr-weblogic-servlet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-jfr-weblogic-servlet.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-joverflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-joverflow.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-jvm-browser-flight-recorder-node-expanded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-jvm-browser-flight-recorder-node-expanded.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-latency-before-view-all-threads.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-latency-before-view-all-threads.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-latency-fixed-all-threads.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-latency-fixed-all-threads.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-latency-fixed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-latency-fixed.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-launch-with-workspace-plugins.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-launch-with-workspace-plugins.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-launch-wizard-jfr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-launch-wizard-jfr.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-lock-instances-page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-lock-instances-page.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-log4j-contention-add-filter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-log4j-contention-add-filter.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-log4j-contention-add-grouping.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-log4j-contention-add-grouping.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-log4j-contention-bug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-log4j-contention-bug.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-log4j-contention-combine-filter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-log4j-contention-combine-filter.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-log4j-contention-show-search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-log4j-contention-show-search.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-management-console-blank-chart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-management-console-blank-chart.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-management-console-thread-count.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-management-console-thread-count.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-management-console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-management-console.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-mbean-browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-mbean-browser.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-memory-page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-memory-page.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-method-profiling-hotmethods.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-method-profiling-hotmethods.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-perspective-button-toggle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-perspective-button-toggle.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-perspective-jvm-browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-perspective-jvm-browser.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-referer-tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-referer-tree.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-rename-custom-page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-rename-custom-page.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-request-log-add-column.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-request-log-add-column.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-request-log-context-menu-group-by-ecid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-request-log-context-menu-group-by-ecid.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-request-log-ecid-grouping.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-request-log-ecid-grouping.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-request-log-remove-type-filter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-request-log-remove-type-filter.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-request-log-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-request-log-view.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-reset-class-histogram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-reset-class-histogram.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-reset-to-default-controls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-reset-to-default-controls.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-stacktrace-line-numbers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-stacktrace-line-numbers.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-stacktrace-next-frame-group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-stacktrace-next-frame-group.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-stacktrace-tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-stacktrace-tree.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-start-flight-recording.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-start-flight-recording.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-thread-count-freeze-graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-thread-count-freeze-graph.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-thread-graph-deadlocked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-thread-graph-deadlocked.png -------------------------------------------------------------------------------- /docs/images/eclipse-jmc-trigger-alerts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-jmc-trigger-alerts.png -------------------------------------------------------------------------------- /docs/images/eclipse-plugin-project-export-rule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-plugin-project-export-rule.png -------------------------------------------------------------------------------- /docs/images/eclipse-plugin-project-no-ui-contribution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-plugin-project-no-ui-contribution.png -------------------------------------------------------------------------------- /docs/images/eclipse-plugin-project-simple-jfr-rule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-plugin-project-simple-jfr-rule.png -------------------------------------------------------------------------------- /docs/images/eclipse-plugin-project-window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-plugin-project-window.png -------------------------------------------------------------------------------- /docs/images/eclipse-plugin-project-wizard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-plugin-project-wizard.png -------------------------------------------------------------------------------- /docs/images/eclipse-preferences-execution-environments.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-preferences-execution-environments.png -------------------------------------------------------------------------------- /docs/images/eclipse-preferences-installed-jres.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-preferences-installed-jres.png -------------------------------------------------------------------------------- /docs/images/eclipse-run-configurations-application-idle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-run-configurations-application-idle.png -------------------------------------------------------------------------------- /docs/images/eclipse-run-do-nothing-program.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-run-do-nothing-program.png -------------------------------------------------------------------------------- /docs/images/eclipse-workspace-projects-loaded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/eclipse-workspace-projects-loaded.png -------------------------------------------------------------------------------- /docs/images/javafx-application-lasers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/javafx-application-lasers.png -------------------------------------------------------------------------------- /docs/images/jmc-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/jmc-logo.png -------------------------------------------------------------------------------- /docs/images/jmc-start-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/jmc-start-screen.png -------------------------------------------------------------------------------- /docs/images/jmc-welcome-screen-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/jmc-welcome-screen-close.png -------------------------------------------------------------------------------- /docs/images/jmc-welcome-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/docs/images/jmc-welcome-screen.png -------------------------------------------------------------------------------- /projects/01_DoNothing/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /projects/01_DoNothing/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | 01_DoNothing 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /projects/01_DoNothing/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate 4 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=9 5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 6 | org.eclipse.jdt.core.compiler.compliance=9 7 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 8 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 9 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 10 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 11 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 12 | org.eclipse.jdt.core.compiler.release=enabled 13 | org.eclipse.jdt.core.compiler.source=9 14 | -------------------------------------------------------------------------------- /projects/01_DoNothing/Launchers/DoNothing Auto Record.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /projects/01_DoNothing/Launchers/DoNothing Literally 1.7.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /projects/01_DoNothing/Launchers/DoNothing Literally.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /projects/01_DoNothing/Launchers/DoNothing.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /projects/01_DoNothing/donothing.jfr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/projects/01_DoNothing/donothing.jfr -------------------------------------------------------------------------------- /projects/01_DoNothing/src/se/hirt/jmc/tutorial/donothing/DoNothing.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Marcus Hirt 3 | * 4 | * jmc-tutorial is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * jmc-tutorial is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with jmc-tutorial. If not, see . 16 | */ 17 | package se.hirt.jmc.tutorial.donothing; 18 | 19 | import java.io.IOException; 20 | 21 | /** 22 | * Program that doesn't do much. 23 | */ 24 | public class DoNothing { 25 | public static void main(String[] args) throws IOException { 26 | System.out.println("Press to quit!"); 27 | System.in.read(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /projects/02_JFR_HotMethods/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /projects/02_JFR_HotMethods/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | 02_JFR_HotMethods 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /projects/02_JFR_HotMethods/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled 3 | org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore 4 | org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull 5 | org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault 6 | org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable 7 | org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled 8 | org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning 9 | org.eclipse.jdt.core.compiler.problem.autoboxing=ignore 10 | org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning 11 | org.eclipse.jdt.core.compiler.problem.deadCode=warning 12 | org.eclipse.jdt.core.compiler.problem.deprecation=ignore 13 | org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled 14 | org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled 15 | org.eclipse.jdt.core.compiler.problem.discouragedReference=warning 16 | org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore 17 | org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore 18 | org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore 19 | org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled 20 | org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore 21 | org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning 22 | org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning 23 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=ignore 24 | org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning 25 | org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled 26 | org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning 27 | org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning 28 | org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore 29 | org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore 30 | org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning 31 | org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore 32 | org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore 33 | org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled 34 | org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore 35 | org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore 36 | org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled 37 | org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning 38 | org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore 39 | org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning 40 | org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning 41 | org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore 42 | org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning 43 | org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error 44 | org.eclipse.jdt.core.compiler.problem.nullReference=warning 45 | org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error 46 | org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning 47 | org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning 48 | org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore 49 | org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore 50 | org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore 51 | org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore 52 | org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning 53 | org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning 54 | org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore 55 | org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore 56 | org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore 57 | org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore 58 | org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore 59 | org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled 60 | org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning 61 | org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled 62 | org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled 63 | org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled 64 | org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore 65 | org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning 66 | org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled 67 | org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning 68 | org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning 69 | org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore 70 | org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning 71 | org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore 72 | org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore 73 | org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore 74 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore 75 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled 76 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled 77 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled 78 | org.eclipse.jdt.core.compiler.problem.unusedImport=warning 79 | org.eclipse.jdt.core.compiler.problem.unusedLabel=warning 80 | org.eclipse.jdt.core.compiler.problem.unusedLocal=warning 81 | org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore 82 | org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore 83 | org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled 84 | org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled 85 | org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled 86 | org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning 87 | org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore 88 | org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning 89 | org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning 90 | -------------------------------------------------------------------------------- /projects/02_JFR_HotMethods/Launchers/HotMethods Auto Record.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /projects/02_JFR_HotMethods/Launchers/HotMethods.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /projects/02_JFR_HotMethods/Readme.txt: -------------------------------------------------------------------------------- 1 | This example illustrates the hot methods tab in JRA and JFR. 2 | 3 | 1. Make a recording or open the prepared recording (hotmethods_before.jfr) and check where most of the time is spent. 4 | 2. Can you make the application run faster? 5 | 6 | Hints below if you get stuck... 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | Tip 1: You can make the program run a lot faster by simply changing _one_ line. 53 | 54 | Tip 2: We spend a lot of time in the LinkedList.equals(Object)/LinkedList.indexOf(Object) method. 55 | 56 | Tip 3: Looking at the trace to the hottest method, shows that we are passing through the contains method. 57 | 58 | Tip 4: Contains in a linked list is proportional to the number of entries. 59 | 60 | Tip 5: A HashSet will, on average, do the trick in constant time. 61 | 62 | Tip 6: Find out where contains is being called from (Method Profiling page, look at what keeps calling the contains method). 63 | 64 | Tip 7 (total spoiler, don't read this): Change line 28 in HolderOfUniqueValues.java to read: collection = new HashSet(); Run and compare. 65 | 66 | Tip 8: You can compare the time it takes to run the individual work units by looking at the work events, either by enabling the Thread activity lane in the Java Application page, or by looking at them in the Event Browser page. -------------------------------------------------------------------------------- /projects/02_JFR_HotMethods/hotmethods_before.jfr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/projects/02_JFR_HotMethods/hotmethods_before.jfr -------------------------------------------------------------------------------- /projects/02_JFR_HotMethods/hotmethods_fixed.jfr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/projects/02_JFR_HotMethods/hotmethods_fixed.jfr -------------------------------------------------------------------------------- /projects/02_JFR_HotMethods/src/se/hirt/jmc/tutorial/hotmethods/HolderOfUniqueValues.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Marcus Hirt 3 | * 4 | * jmc-tutorial is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * jmc-tutorial is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with jmc-tutorial. If not, see . 16 | */ 17 | package se.hirt.jmc.tutorial.hotmethods; 18 | 19 | import java.util.Collection; 20 | import java.util.LinkedList; 21 | 22 | /** 23 | * Never mind that this is a ridiculous class to begin with. A one line change can make this example 24 | * run a lot faster. 25 | */ 26 | public class HolderOfUniqueValues { 27 | private Collection collection; 28 | 29 | public HolderOfUniqueValues() { 30 | collection = new LinkedList<>(); 31 | } 32 | 33 | // Hint: This creates a list of unique elements! 34 | public void initialize(int moduloDivisor) { 35 | collection.clear(); 36 | for (int i = 1; i < 10000; i++) { 37 | if ((i % moduloDivisor) != 0) 38 | collection.add(i); 39 | } 40 | } 41 | 42 | protected Collection getCollection() { 43 | return collection; 44 | } 45 | 46 | public int countIntersection(HolderOfUniqueValues other) { 47 | int count = 0; 48 | for (Integer i : collection) { 49 | if (other.getCollection().contains(i)) { 50 | count++; 51 | } 52 | } 53 | return count; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /projects/02_JFR_HotMethods/src/se/hirt/jmc/tutorial/hotmethods/HotMethods.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Marcus Hirt 3 | * 4 | * jmc-tutorial is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * jmc-tutorial is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with jmc-tutorial. If not, see . 16 | */ 17 | package se.hirt.jmc.tutorial.hotmethods; 18 | 19 | import java.io.IOException; 20 | 21 | /** 22 | * Never mind this class. These are not the droi... This is not the class you're looking for. It's 23 | * just for setting up the worker threads. The problem is elsewhere. ;) 24 | */ 25 | public class HotMethods { 26 | // Hint: You may want to set NUMBER_OF_THREADS close to the number of hardware threads for maximum saturation 27 | private static final int NUMBER_OF_THREADS = 4; 28 | 29 | public static void main(String[] args) throws IOException { 30 | ThreadGroup threadGroup = new ThreadGroup("Workers"); 31 | Thread[] threads = new Thread[NUMBER_OF_THREADS]; 32 | for (int i = 0; i < threads.length; i++) { 33 | threads[i] = new Thread(threadGroup, new Worker(), "Worker Thread " + i); 34 | threads[i].setDaemon(true); 35 | threads[i].start(); 36 | } 37 | System.out.print("Press enter to quit!"); 38 | System.out.flush(); 39 | System.in.read(); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /projects/02_JFR_HotMethods/src/se/hirt/jmc/tutorial/hotmethods/WorkEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Marcus Hirt 3 | * 4 | * jmc-tutorial is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * jmc-tutorial is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with jmc-tutorial. If not, see . 16 | */ 17 | package se.hirt.jmc.tutorial.hotmethods; 18 | 19 | import jdk.jfr.Category; 20 | import jdk.jfr.Description; 21 | import jdk.jfr.Event; 22 | import jdk.jfr.Label; 23 | 24 | /** 25 | * This is a JDK Flight Recorder event. 26 | */ 27 | @Label("Work") 28 | @Category("02_JFR_HotMethods") 29 | @Description("Data from one loop run in the worker thread") 30 | public class WorkEvent extends Event { 31 | @Label("Intersection Size") 32 | @Description("The number of values that were the same in the two collections") 33 | private int intersectionSize; 34 | 35 | public int getIntersectionSize() { 36 | return intersectionSize; 37 | } 38 | 39 | public void setIntersectionSize(int intersectionSize) { 40 | this.intersectionSize = intersectionSize; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /projects/02_JFR_HotMethods/src/se/hirt/jmc/tutorial/hotmethods/Worker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Marcus Hirt 3 | * 4 | * jmc-tutorial is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * jmc-tutorial is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with jmc-tutorial. If not, see . 16 | */ 17 | package se.hirt.jmc.tutorial.hotmethods; 18 | 19 | /** 20 | * The code run in the worker threads. One JFR event will be generated per lap in the loop, 21 | * recording the "result". 22 | */ 23 | public class Worker implements Runnable { 24 | public void run() { 25 | while (true) { 26 | WorkEvent event = new WorkEvent(); 27 | event.begin(); 28 | HolderOfUniqueValues i1 = new HolderOfUniqueValues(); 29 | HolderOfUniqueValues i2 = new HolderOfUniqueValues(); 30 | i1.initialize(3); 31 | i2.initialize(5); 32 | int intersectionSize = i1.countIntersection(i2); 33 | event.setIntersectionSize(intersectionSize); 34 | event.end(); 35 | event.commit(); 36 | Thread.yield(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /projects/03_JFR_Latencies/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /projects/03_JFR_Latencies/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | 03_JFR_Latencies 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /projects/03_JFR_Latencies/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled 3 | org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore 4 | org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull 5 | org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault 6 | org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable 7 | org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled 8 | org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning 9 | org.eclipse.jdt.core.compiler.problem.autoboxing=ignore 10 | org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning 11 | org.eclipse.jdt.core.compiler.problem.deadCode=warning 12 | org.eclipse.jdt.core.compiler.problem.deprecation=ignore 13 | org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled 14 | org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled 15 | org.eclipse.jdt.core.compiler.problem.discouragedReference=ignore 16 | org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore 17 | org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore 18 | org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore 19 | org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled 20 | org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore 21 | org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning 22 | org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning 23 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=ignore 24 | org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning 25 | org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled 26 | org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning 27 | org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning 28 | org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore 29 | org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore 30 | org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning 31 | org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore 32 | org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore 33 | org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled 34 | org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore 35 | org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore 36 | org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled 37 | org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning 38 | org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore 39 | org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning 40 | org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning 41 | org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore 42 | org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning 43 | org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error 44 | org.eclipse.jdt.core.compiler.problem.nullReference=warning 45 | org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error 46 | org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning 47 | org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning 48 | org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore 49 | org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore 50 | org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore 51 | org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore 52 | org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning 53 | org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning 54 | org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore 55 | org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore 56 | org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore 57 | org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore 58 | org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore 59 | org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled 60 | org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning 61 | org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled 62 | org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled 63 | org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled 64 | org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore 65 | org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning 66 | org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled 67 | org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning 68 | org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning 69 | org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore 70 | org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning 71 | org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore 72 | org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore 73 | org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore 74 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore 75 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled 76 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled 77 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled 78 | org.eclipse.jdt.core.compiler.problem.unusedImport=warning 79 | org.eclipse.jdt.core.compiler.problem.unusedLabel=warning 80 | org.eclipse.jdt.core.compiler.problem.unusedLocal=warning 81 | org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore 82 | org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore 83 | org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled 84 | org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled 85 | org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled 86 | org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning 87 | org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore 88 | org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning 89 | org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning 90 | -------------------------------------------------------------------------------- /projects/03_JFR_Latencies/Launchers/Latencies Auto Record.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /projects/03_JFR_Latencies/Launchers/Latencies.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /projects/03_JFR_Latencies/Readme.txt: -------------------------------------------------------------------------------- 1 | This example features a logger that is shared between a bunch of worker threads. 2 | Take a look at the pre-recorded latency_before.jfr file. 3 | 4 | 1. The idea with the worker threads is to get work done in parallel. How many 5 | threads are actually running in parallel? Why? 6 | 7 | 2. Can you change the application by simply removing a single key word in one of the files to improve things? 8 | 9 | 3. Can you think of other ways to change the application to accomplish this? 10 | 11 | Help below if you get stuck. 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 1. Look at the latency_before.jfr recording and check the automated analysis. What is flagged? 67 | 68 | 2. What class is all of the contention on? (Jump to the page associated with the higest ranked rules - Lock Instances.) 69 | 70 | 3. The blocking events all seem to be due to calls to the Log method. 71 | 72 | 4. There are a few ways to fix this available to us. We can cut the call to the logger altogether. If the logging doesn't use a shared resource, 73 | we can just remove the synchronization from the log method. We could also provide each thread with its own logger, carefully making sure that 74 | we do not end up blocking on another shared resource instead. Of course, this is just an example, and no such limitations exist - any of these 75 | solutions would do. 76 | 77 | 5. The latency_fixed.jfr recording shows the situation after the fix. The problem is no longer flagged. For a nice visual look at the difference, follow the lab instructions. -------------------------------------------------------------------------------- /projects/03_JFR_Latencies/latency_before.jfr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/projects/03_JFR_Latencies/latency_before.jfr -------------------------------------------------------------------------------- /projects/03_JFR_Latencies/latency_fixed.jfr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/projects/03_JFR_Latencies/latency_fixed.jfr -------------------------------------------------------------------------------- /projects/03_JFR_Latencies/src/se/hirt/jmc/tutorial/latencies/Latencies.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Marcus Hirt 3 | * 4 | * jmc-tutorial is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * jmc-tutorial is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with jmc-tutorial. If not, see . 16 | */ 17 | package se.hirt.jmc.tutorial.latencies; 18 | 19 | import java.io.IOException; 20 | 21 | /** 22 | * Class used to run the latency problem example. 23 | */ 24 | public class Latencies { 25 | public static void main(String[] args) throws InterruptedException, IOException { 26 | ThreadGroup threadGroup = new ThreadGroup("Workers"); 27 | Thread.sleep(2000); 28 | Thread[] threads; 29 | threads = new Thread[20]; 30 | for (int i = 0; i < threads.length; i++) { 31 | threads[i] = new Thread(threadGroup, new Worker(i, 30_000_000), "Worker Thread " + i); 32 | threads[i].setDaemon(true); 33 | System.out.println("Starting " + threads[i].getName() + "..."); 34 | threads[i].start(); 35 | } 36 | System.out.println("...all prepared!"); 37 | System.out.println("Press to quit!"); 38 | System.out.flush(); 39 | System.in.read(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /projects/03_JFR_Latencies/src/se/hirt/jmc/tutorial/latencies/LogEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Marcus Hirt 3 | * 4 | * jmc-tutorial is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * jmc-tutorial is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with jmc-tutorial. If not, see . 16 | */ 17 | package se.hirt.jmc.tutorial.latencies; 18 | 19 | import jdk.jfr.Category; 20 | import jdk.jfr.Description; 21 | import jdk.jfr.Event; 22 | import jdk.jfr.Label; 23 | 24 | /** 25 | * This is the event emitted by our "Logger". 26 | */ 27 | @Label("Log Entry") 28 | @Category("03_JFR_Latencies") 29 | public class LogEvent extends Event { 30 | @Label("Message") 31 | @Description("The logged message") 32 | private String message; 33 | 34 | public LogEvent(String message) { 35 | this.message = message; 36 | } 37 | 38 | public String getMessage() { 39 | return message; 40 | } 41 | 42 | public void setMessage(String message) { 43 | this.message = message; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /projects/03_JFR_Latencies/src/se/hirt/jmc/tutorial/latencies/Logger.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Marcus Hirt 3 | * 4 | * jmc-tutorial is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * jmc-tutorial is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with jmc-tutorial. If not, see . 16 | */ 17 | package se.hirt.jmc.tutorial.latencies; 18 | 19 | /** 20 | * This class contains our problematic logger. 21 | */ 22 | public class Logger { 23 | private static Logger myInstance = new Logger(); 24 | 25 | public static Logger getLogger() { 26 | return myInstance; 27 | } 28 | 29 | public synchronized void log(String text) { 30 | LogEvent event = new LogEvent(text); 31 | event.begin(); 32 | // Do logging here 33 | // Write the text to a database or similar... 34 | try { 35 | // Simulate that this takes a little while. 36 | Thread.sleep(200); 37 | } catch (InterruptedException e) { 38 | // Don't care. 39 | } 40 | event.end(); 41 | event.commit(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /projects/03_JFR_Latencies/src/se/hirt/jmc/tutorial/latencies/WorkEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Marcus Hirt 3 | * 4 | * jmc-tutorial is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * jmc-tutorial is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with jmc-tutorial. If not, see . 16 | */ 17 | package se.hirt.jmc.tutorial.latencies; 18 | 19 | import jdk.jfr.Category; 20 | import jdk.jfr.Description; 21 | import jdk.jfr.Event; 22 | import jdk.jfr.Label; 23 | 24 | /** 25 | * Example event showing that not much is needed to time stuff using the JDK Flight Recorder. 26 | */ 27 | @Label("Work") 28 | @Category("03_JFR_Latencies") 29 | @Description("A piece of work executed") 30 | public class WorkEvent extends Event { 31 | } 32 | -------------------------------------------------------------------------------- /projects/03_JFR_Latencies/src/se/hirt/jmc/tutorial/latencies/Worker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Marcus Hirt 3 | * 4 | * jmc-tutorial is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * jmc-tutorial is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with jmc-tutorial. If not, see . 16 | */ 17 | package se.hirt.jmc.tutorial.latencies; 18 | 19 | /** 20 | * This is what will run in the worker threads. It will do some arbitrary work, and then log some 21 | * message about work being done. 22 | */ 23 | public class Worker implements Runnable { 24 | public final static Logger LOGGER = Logger.getLogger(); 25 | private final int id; 26 | private final int loopCount; 27 | 28 | public Worker(int id, int loopCount) { 29 | this.id = id; 30 | this.loopCount = loopCount; 31 | } 32 | 33 | @Override 34 | public void run() { 35 | while (true) { 36 | WorkEvent event = new WorkEvent(); 37 | event.begin(); 38 | int x = 1; 39 | int y = 1; 40 | for (int i = 1; i < loopCount; i++) { 41 | x += 1; 42 | y = y % (this.loopCount + 3); 43 | if (x % (this.loopCount + 4) == 0 || y == 0) { 44 | System.out.println("Should not happen"); 45 | } 46 | } 47 | event.end(); 48 | event.commit(); 49 | LOGGER.log("Worker " + id + " reporting work done"); 50 | Thread.yield(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /projects/04_JFR_GC/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /projects/04_JFR_GC/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | 04_JFR_GC 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /projects/04_JFR_GC/Launchers/Allocations Auto Record.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /projects/04_JFR_GC/Launchers/Allocations.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /projects/04_JFR_GC/Readme.txt: -------------------------------------------------------------------------------- 1 | This example shows allocation behavior due to a suboptimal choice in datatypes. 2 | 3 | 1. Look at the allocation_before.jfr recording. 4 | 2. Go to the Garbage Collections page. Marvel at the frequency of garbage collections. 5 | 2. Look at the Memory page. What kind of object seems to be the one mostly allocated. 6 | 3. What is causing the allocations? 7 | 4. What is causing the garbage collections? 8 | 5. Can a simple change of data type in one of the classes help? 9 | 6. After fixing, how many garbage collections do you get? 10 | 7. What does the allocation behaviour look like? 11 | 12 | Help below if you get stuck: 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | (In JMC 7 the reason is shown directly in the automated analysis. Let's ignore that for a bit.) 69 | 1. Memory tab helps. TLAB page shows even more detail. 70 | 2. Integer allocations are abundant. 71 | 3. Trace shows that valueOf causes the allocations. 72 | 4. Allocator autoboxes int to Integer, causing the allocations. 73 | 5. Switching to Integer in the MyAlloc inner class will help (replace all int with Integer). Typically, 74 | when primitive types are used as index in HashMaps, storing the object version is a better idea than 75 | going back and forth between the primitive type and Object version. 76 | 6. After fixing, there are no garbage collections anymore. Check and compare Garbage Collections pages for the two recordings. 77 | 7. Of course, in JMC 7 the problem is explained directly in the automated analysis results page... -------------------------------------------------------------------------------- /projects/04_JFR_GC/allocation_before.jfr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/projects/04_JFR_GC/allocation_before.jfr -------------------------------------------------------------------------------- /projects/04_JFR_GC/allocation_fixed.jfr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/projects/04_JFR_GC/allocation_fixed.jfr -------------------------------------------------------------------------------- /projects/04_JFR_GC/src/se/hirt/jmc/tutorial/gc/Allocations.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Marcus Hirt 3 | * 4 | * jmc-tutorial is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * jmc-tutorial is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with jmc-tutorial. If not, see . 16 | */ 17 | package se.hirt.jmc.tutorial.gc; 18 | import java.io.IOException; 19 | 20 | /** 21 | * Example causing a lot of memory pressure. 22 | */ 23 | public class Allocations { 24 | private static final int NUMBER_OF_THREADS = 2; 25 | 26 | public static void main(String[] args) throws IOException { 27 | ThreadGroup threadGroup = new ThreadGroup("Workers"); 28 | Thread[] threads = new Thread[NUMBER_OF_THREADS]; 29 | for (int i = 0; i < threads.length; i++) { 30 | threads[i] = new Thread(threadGroup, new Allocator(), "Allocator Thread " + i); 31 | threads[i].setDaemon(true); 32 | threads[i].start(); 33 | } 34 | System.out.print("Press to quit!"); 35 | System.out.flush(); 36 | System.in.read(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /projects/04_JFR_GC/src/se/hirt/jmc/tutorial/gc/Allocator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Marcus Hirt 3 | * 4 | * jmc-tutorial is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * jmc-tutorial is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with jmc-tutorial. If not, see . 16 | */ 17 | package se.hirt.jmc.tutorial.gc; 18 | 19 | import java.util.Collection; 20 | import java.util.HashMap; 21 | import java.util.Map; 22 | 23 | /** 24 | * Will allocate a map with ExampleMapContent, and then proceeds to check for each ExampleMapContent 25 | * in the map, that it is really, really in the map. Over and over. ;) 26 | */ 27 | public final class Allocator implements Runnable { 28 | private final static int SET_SIZE = 10_000; 29 | private final Map map; 30 | 31 | public Allocator() { 32 | map = createMap(SET_SIZE); 33 | } 34 | 35 | @Override 36 | public void run() { 37 | long yieldCounter = 0; 38 | while (true) { 39 | Collection myAllocSet = map.values(); 40 | for (ExampleMapContent c : myAllocSet) { 41 | if (!map.containsKey(c.getId())) 42 | System.out.println("Now this is strange!"); 43 | if (++yieldCounter % 1000 == 0) 44 | Thread.yield(); 45 | } 46 | } 47 | } 48 | 49 | private static Map createMap(int count) { 50 | Map map = new HashMap<>(); 51 | for (int i = 0; i < count; i++) { 52 | map.put(i, new ExampleMapContent(i)); 53 | } 54 | return map; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /projects/04_JFR_GC/src/se/hirt/jmc/tutorial/gc/ExampleMapContent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Marcus Hirt 3 | * 4 | * jmc-tutorial is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * jmc-tutorial is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with jmc-tutorial. If not, see . 16 | */ 17 | 18 | package se.hirt.jmc.tutorial.gc; 19 | 20 | /** 21 | * The kind of object that will be in the map. 22 | */ 23 | final class ExampleMapContent { 24 | private final int id; 25 | 26 | ExampleMapContent(int id) { 27 | this.id = id; 28 | } 29 | 30 | int getId() { 31 | return id; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /projects/05_JFR_MemoryLeak/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /projects/05_JFR_MemoryLeak/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | 05_JFR_MemoryLeak 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /projects/05_JFR_MemoryLeak/Launchers/Leak Auto Record.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /projects/05_JFR_MemoryLeak/Launchers/Leak.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /projects/05_JFR_MemoryLeak/Launchers/MultiLoaderLeak.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /projects/05_JFR_MemoryLeak/Readme.txt: -------------------------------------------------------------------------------- 1 | This application has a memory leak. 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 1. Run Leak with the auto record launcher and wait until the recording is written (8 minutes), 45 | or simply open the memoryleak_before.jfr file. 46 | 2. Open the recording. 47 | 3. Check out the Live Objects page. 48 | 4. What types (instances of what types) do you think are leaking? 49 | 5. From where are they being referenced? 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | No hints here yet. Open the lab instructions for hints. -------------------------------------------------------------------------------- /projects/05_JFR_MemoryLeak/memoryleak_before.jfr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/projects/05_JFR_MemoryLeak/memoryleak_before.jfr -------------------------------------------------------------------------------- /projects/05_JFR_MemoryLeak/memoryleak_fixed.jfr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/projects/05_JFR_MemoryLeak/memoryleak_fixed.jfr -------------------------------------------------------------------------------- /projects/05_JFR_MemoryLeak/src/se/hirt/jmc/tutorial/memleak/CustomLoader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Marcus Hirt 3 | * 4 | * jmc-tutorial is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * jmc-tutorial is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with jmc-tutorial. If not, see . 16 | */ 17 | package se.hirt.jmc.tutorial.memleak; 18 | 19 | import java.io.ByteArrayOutputStream; 20 | import java.io.IOException; 21 | import java.io.InputStream; 22 | 23 | /** 24 | * Custom loader to leak in multiple different class loaders. 25 | */ 26 | public class CustomLoader extends ClassLoader { 27 | private static final int BUFFER_SIZE = 4096; 28 | private final String name; 29 | private int loadedClasses; 30 | 31 | public CustomLoader(String classLoaderName) { 32 | this.name = classLoaderName; 33 | } 34 | 35 | protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { 36 | Class clazz = findLoadedClass(name); 37 | if (clazz != null) { 38 | return clazz; 39 | } 40 | String classFileName = name.replace('.', '/') + ".class"; 41 | byte[] classBytes = null; 42 | 43 | try { 44 | InputStream in = getResourceAsStream(classFileName); 45 | byte[] buffer = new byte[BUFFER_SIZE]; 46 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 47 | int n = -1; 48 | while ((n = in.read(buffer, 0, BUFFER_SIZE)) != -1) { 49 | out.write(buffer, 0, n); 50 | } 51 | classBytes = out.toByteArray(); 52 | } catch (IOException e) { 53 | throw new ClassNotFoundException("Could not load the class " + name + " from " + classFileName, e); 54 | } 55 | 56 | if (classBytes == null) { 57 | throw new ClassNotFoundException("Cannot load the class " + name); 58 | } 59 | try { 60 | clazz = defineClass(name, classBytes, 0, classBytes.length); 61 | if (resolve) { 62 | resolveClass(clazz); 63 | } 64 | loadedClasses++; 65 | } catch (SecurityException e) { 66 | // Delegate to parent for system classes 67 | clazz = super.loadClass(name, resolve); 68 | } 69 | return clazz; 70 | } 71 | 72 | public int getNumberOfLoadedClasses() { 73 | return loadedClasses; 74 | } 75 | 76 | public String getName() { 77 | return name; 78 | } 79 | 80 | public String toString() { 81 | return "CustomLoader [name=" + getName() + ", classes loaded=" + getNumberOfLoadedClasses() + "]"; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /projects/05_JFR_MemoryLeak/src/se/hirt/jmc/tutorial/memleak/Leak.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Marcus Hirt 3 | * 4 | * jmc-tutorial is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * jmc-tutorial is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with jmc-tutorial. If not, see . 16 | */ 17 | package se.hirt.jmc.tutorial.memleak; 18 | 19 | import java.util.Hashtable; 20 | import java.util.List; 21 | import java.io.IOException; 22 | import java.util.ArrayList; 23 | 24 | /** 25 | * Simple memory leak demo. 26 | */ 27 | public class Leak { 28 | private static class DemoObject { 29 | private long position; 30 | @SuppressWarnings("unused") 31 | long myField1 = 1; 32 | @SuppressWarnings("unused") 33 | long myField2 = 2; 34 | @SuppressWarnings("unused") 35 | char[] chunk = new char[255]; 36 | 37 | public DemoObject(int pos) { 38 | position = pos; 39 | } 40 | 41 | public int hashCode() { 42 | return (int) position; 43 | } 44 | 45 | public boolean equals(Object o) { 46 | return (o instanceof DemoObject) && (o.hashCode() == position); 47 | } 48 | } 49 | 50 | private static class TransientAllocator implements Runnable { 51 | public void run() { 52 | while (true) { 53 | // Alloc transients 54 | List junkList = new ArrayList(); 55 | for (int i = 0; i < 1000; i++) { 56 | junkList.add(new Object()); 57 | for (int j = 0; j < 10; j++) 58 | // Keep busy yielding for a little 59 | // while... 60 | Thread.yield(); 61 | } 62 | } 63 | } 64 | } 65 | 66 | private static class DemoThread implements Runnable { 67 | private Hashtable table; 68 | private int leakspeed; 69 | 70 | DemoThread(Hashtable table, int leakspeed) { 71 | this.table = table; 72 | this.leakspeed = leakspeed; 73 | } 74 | 75 | public void run() { 76 | int total = 0; 77 | while (true) { 78 | for (int i = 0; i <= 100; i++) 79 | put(total + i); 80 | 81 | for (int i = 0; i <= 100 - leakspeed; i++) 82 | remove(total + i); 83 | 84 | total += 101; 85 | 86 | for (int i = 0; i < 10; i++) { 87 | // Keep busy yielding for a little while... 88 | Thread.yield(); 89 | } 90 | try { 91 | Thread.sleep(70); 92 | } catch (InterruptedException e) { 93 | } 94 | } 95 | } 96 | 97 | private void put(int n) { 98 | table.put(new DemoObject(n), "foo"); 99 | } 100 | 101 | private String remove(int n) { 102 | return table.remove(new DemoObject(n)); 103 | } 104 | } 105 | 106 | public static void main(String[] args) throws IOException { 107 | Hashtable h = new Hashtable(); 108 | Thread[] threads; 109 | int leakspeed = 1; 110 | int threadCount; 111 | 112 | if (args.length < 1 || args.length > 2) { 113 | threadCount = 2; 114 | } else { 115 | threadCount = Integer.parseInt(args[0]); 116 | } 117 | threads = new Thread[threadCount]; 118 | 119 | if (args.length == 2) { 120 | leakspeed = Integer.parseInt(args[1]); 121 | } 122 | 123 | System.out.println(String.format("Starting leak with %d threads and a leak speed of %d", threadCount, leakspeed)); 124 | System.out.print("Starting threads... "); 125 | for (int i = 0; i < threads.length; i++) { 126 | threads[i] = new Thread(new DemoThread(h, leakspeed)); 127 | threads[i].setDaemon(true); 128 | threads[i].start(); 129 | } 130 | System.out.println("done!"); 131 | startAllocThread(); 132 | System.out.println("Press to quit!"); 133 | System.in.read(); 134 | } 135 | 136 | private static void startAllocThread() { 137 | Thread thread = new Thread(new TransientAllocator(), "Transient Allocator"); 138 | thread.setDaemon(true); 139 | thread.start(); 140 | } 141 | 142 | public static void startLeak() { 143 | Hashtable h = new Hashtable(); 144 | Thread t = new Thread(new DemoThread(h, 1), "Leaking Allocator"); 145 | t.start(); 146 | } 147 | 148 | public static void startFastLeak() { 149 | Hashtable h = new Hashtable(); 150 | Thread t = new Thread(new DemoThread(h, 2), "Fast Leaking Allocator"); 151 | t.start(); 152 | } 153 | 154 | public static void startNonLeak() { 155 | Hashtable h = new Hashtable(); 156 | Thread t = new Thread(new DemoThread(h, 0), "Not Leaking Allocator"); 157 | t.start(); 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /projects/05_JFR_MemoryLeak/src/se/hirt/jmc/tutorial/memleak/MultiLoaderLeak.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Marcus Hirt 3 | * 4 | * jmc-tutorial is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * jmc-tutorial is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with jmc-tutorial. If not, see . 16 | */ 17 | 18 | package se.hirt.jmc.tutorial.memleak; 19 | 20 | import java.lang.reflect.InvocationTargetException; 21 | import java.lang.reflect.Method; 22 | 23 | /** 24 | * Creates a memory leak in three different class loaders, two leaking at different speeds, and one 25 | * not leaking at all. 26 | */ 27 | public class MultiLoaderLeak { 28 | public static void main(String[] args) throws ClassNotFoundException, IllegalArgumentException, SecurityException, 29 | IllegalAccessException, InvocationTargetException, NoSuchMethodException { 30 | // Create three different loaders, A, B and C. 31 | // Load the Leak class in all three separately, and kick off two leaking, 32 | // and one that isn't. 33 | CustomLoader loaderA = new CustomLoader("A"); 34 | CustomLoader loaderB = new CustomLoader("B"); 35 | CustomLoader loaderC = new CustomLoader("C"); 36 | runMethod("startLeak", loaderA.loadClass("Leak")); 37 | runMethod("startNonLeak", loaderB.loadClass("Leak")); 38 | runMethod("startFastLeak", loaderC.loadClass("Leak")); 39 | } 40 | 41 | private static void runMethod(String method, Class clazz) throws IllegalArgumentException, SecurityException, 42 | IllegalAccessException, InvocationTargetException, NoSuchMethodException { 43 | Method m = clazz.getMethod(method, new Class[0]); 44 | m.invoke(null, new Object[0]); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /projects/06_JFR_WLS/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /projects/06_JFR_WLS/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | 06_JFR_WLS 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /projects/06_JFR_WLS/jmcwldf.jfc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 10 ms 111 | 112 | false 113 | 114 | false 115 | 116 | true 117 | 118 | 119 | 120 | 121 | true 122 | everyChunk 123 | 124 | 125 | 126 | true 127 | 1000 ms 128 | 129 | 130 | 131 | true 132 | 1000 ms 133 | 134 | 135 | 136 | true 137 | 138 | 139 | 140 | true 141 | 142 | 143 | 144 | true 145 | true 146 | 10 ms 147 | 148 | 149 | 150 | true 151 | true 152 | 10 ms 153 | 154 | 155 | 156 | true 157 | true 158 | 10 ms 159 | 160 | 161 | 162 | true 163 | true 164 | 10 ms 165 | 166 | 167 | 168 | false 169 | true 170 | 0 ms 171 | 172 | 173 | 174 | false 175 | 176 | 177 | 178 | true 179 | everyChunk 180 | 181 | 182 | 183 | true 184 | everyChunk 185 | 186 | 187 | 188 | true 189 | 10 ms 190 | 191 | 192 | 193 | false 194 | 1 ms 195 | 196 | 197 | 198 | true 199 | 10 ms 200 | 201 | 202 | 203 | true 204 | everyChunk 205 | 206 | 207 | 208 | true 209 | everyChunk 210 | 211 | 212 | 213 | true 214 | everyChunk 215 | 216 | 217 | 218 | true 219 | everyChunk 220 | 221 | 222 | 223 | true 224 | everyChunk 225 | 226 | 227 | 228 | true 229 | everyChunk 230 | 231 | 232 | 233 | false 234 | everyChunk 235 | 236 | 237 | 238 | true 239 | everyChunk 240 | 241 | 242 | 243 | true 244 | everyChunk 245 | 246 | 247 | 248 | true 249 | everyChunk 250 | 251 | 252 | 253 | true 254 | everyChunk 255 | 256 | 257 | 258 | true 259 | everyChunk 260 | 261 | 262 | 263 | false 264 | 265 | 266 | 267 | true 268 | 269 | 270 | 271 | true 272 | 273 | 274 | 275 | true 276 | 277 | 278 | 279 | true 280 | 0 ms 281 | 282 | 283 | 284 | true 285 | 0 ms 286 | 287 | 288 | 289 | true 290 | 0 ms 291 | 292 | 293 | 294 | true 295 | 0 ms 296 | 297 | 298 | 299 | true 300 | 0 ms 301 | 302 | 303 | 304 | true 305 | 0 ms 306 | 307 | 308 | 309 | true 310 | 0 ms 311 | 312 | 313 | 314 | true 315 | 0 ms 316 | 317 | 318 | 319 | true 320 | 0 ms 321 | 322 | 323 | 324 | true 325 | 326 | 327 | 328 | true 329 | 330 | 331 | 332 | true 333 | 334 | 335 | 336 | true 337 | 338 | 339 | 340 | true 341 | 342 | 343 | 344 | true 345 | everyChunk 346 | 347 | 348 | 349 | true 350 | 1000 ms 351 | 352 | 353 | 354 | true 355 | 100 ms 356 | 357 | 358 | 359 | true 360 | 10 s 361 | 362 | 363 | 364 | true 365 | 366 | 367 | 368 | true 369 | everyChunk 370 | 371 | 372 | 373 | true 374 | everyChunk 375 | 376 | 377 | 378 | true 379 | 100 ms 380 | 381 | 382 | 383 | true 384 | 0 ms 385 | 386 | 387 | 388 | true 389 | everyChunk 390 | 391 | 392 | 393 | true 394 | everyChunk 395 | 396 | 397 | 398 | true 399 | 400 | 401 | 402 | true 403 | everyChunk 404 | 405 | 406 | 407 | true 408 | everyChunk 409 | 410 | 411 | 412 | true 413 | 10 s 414 | 415 | 416 | 417 | true 418 | 1000 ms 419 | 420 | 421 | 422 | true 423 | everyChunk 424 | 425 | 426 | 427 | true 428 | everyChunk 429 | 430 | 431 | 432 | true 433 | everyChunk 434 | 435 | 436 | 437 | true 438 | everyChunk 439 | 440 | 441 | 442 | true 443 | true 444 | 445 | 446 | 447 | true 448 | true 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | true 457 | true 458 | 459 | 460 | 461 | true 462 | true 463 | 464 | 465 | 466 | true 467 | 1000 ms 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | true 476 | 477 | 478 | 479 | true 480 | 481 | 482 | 483 | 484 | 485 | -------------------------------------------------------------------------------- /projects/06_JFR_WLS/other/medrec_dont_use.jfr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/projects/06_JFR_WLS/other/medrec_dont_use.jfr -------------------------------------------------------------------------------- /projects/06_JFR_WLS/wldf.jfr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/projects/06_JFR_WLS/wldf.jfr -------------------------------------------------------------------------------- /projects/07_JFR_JavaFX/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /projects/07_JFR_JavaFX/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | 07_JFR_JavaFX 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /projects/07_JFR_JavaFX/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 5 | org.eclipse.jdt.core.compiler.compliance=1.7 6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 10 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 11 | org.eclipse.jdt.core.compiler.source=1.7 12 | -------------------------------------------------------------------------------- /projects/07_JFR_JavaFX/Launchers/GUIMark Auto Record.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /projects/07_JFR_JavaFX/Launchers/GUIMark.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /projects/07_JFR_JavaFX/guimark.jfc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | true 8 | everyChunk 9 | 10 | 11 | 12 | true 13 | 1000 ms 14 | 15 | 16 | 17 | true 18 | 1000 ms 19 | 20 | 21 | 22 | true 23 | 24 | 25 | 26 | true 27 | 28 | 29 | 30 | true 31 | true 32 | 10 ms 33 | 34 | 35 | 36 | true 37 | true 38 | 10 ms 39 | 40 | 41 | 42 | true 43 | true 44 | 10 ms 45 | 46 | 47 | 48 | true 49 | true 50 | 10 ms 51 | 52 | 53 | 54 | false 55 | true 56 | 0 ms 57 | 58 | 59 | 60 | false 61 | 62 | 63 | 64 | true 65 | everyChunk 66 | 67 | 68 | 69 | true 70 | everyChunk 71 | 72 | 73 | 74 | true 75 | 10 ms 76 | 77 | 78 | 79 | false 80 | 1 ms 81 | 82 | 83 | 84 | true 85 | 10 ms 86 | 87 | 88 | 89 | true 90 | 60 s 91 | 92 | 93 | 94 | true 95 | everyChunk 96 | 97 | 98 | 99 | true 100 | everyChunk 101 | 102 | 103 | 104 | true 105 | everyChunk 106 | 107 | 108 | 109 | true 110 | everyChunk 111 | 112 | 113 | 114 | true 115 | everyChunk 116 | 117 | 118 | 119 | true 120 | 121 | 122 | 123 | true 124 | 125 | 126 | 127 | true 128 | 129 | 130 | 131 | true 132 | 133 | 134 | 135 | true 136 | 137 | 138 | 139 | false 140 | everyChunk 141 | 142 | 143 | 144 | true 145 | everyChunk 146 | 147 | 148 | 149 | true 150 | everyChunk 151 | 152 | 153 | 154 | true 155 | everyChunk 156 | 157 | 158 | 159 | true 160 | everyChunk 161 | 162 | 163 | 164 | true 165 | everyChunk 166 | 167 | 168 | 169 | false 170 | 171 | 172 | 173 | true 174 | 175 | 176 | 177 | true 178 | 179 | 180 | 181 | true 182 | 183 | 184 | 185 | true 186 | 187 | 188 | 189 | true 190 | true 191 | 192 | 193 | 194 | true 195 | true 196 | 197 | 198 | 199 | true 200 | 201 | 202 | 203 | true 204 | 0 ms 205 | 206 | 207 | 208 | true 209 | 0 ms 210 | 211 | 212 | 213 | true 214 | 0 ms 215 | 216 | 217 | 218 | true 219 | 0 ms 220 | 221 | 222 | 223 | true 224 | 0 ms 225 | 226 | 227 | 228 | true 229 | 0 ms 230 | 231 | 232 | 233 | true 234 | 0 ms 235 | 236 | 237 | 238 | true 239 | 0 ms 240 | 241 | 242 | 243 | false 244 | 0 ms 245 | 246 | 247 | 248 | true 249 | 250 | 251 | 252 | true 253 | 254 | 255 | 256 | true 257 | 258 | 259 | 260 | true 261 | 262 | 263 | 264 | true 265 | 266 | 267 | 268 | false 269 | true 270 | 271 | 272 | 273 | true 274 | everyChunk 275 | 276 | 277 | 278 | true 279 | 1000 ms 280 | 281 | 282 | 283 | true 284 | 100 ms 285 | 286 | 287 | 288 | true 289 | 10 s 290 | 291 | 292 | 293 | true 294 | 295 | 296 | 297 | true 298 | everyChunk 299 | 300 | 301 | 302 | true 303 | everyChunk 304 | 305 | 306 | 307 | true 308 | 100 ms 309 | 310 | 311 | 312 | true 313 | everyChunk 314 | 315 | 316 | 317 | true 318 | everyChunk 319 | 320 | 321 | 322 | true 323 | 324 | 325 | 326 | true 327 | everyChunk 328 | 329 | 330 | 331 | true 332 | everyChunk 333 | 334 | 335 | 336 | true 337 | 10 s 338 | 339 | 340 | 341 | true 342 | 1000 ms 343 | 344 | 345 | 346 | true 347 | everyChunk 348 | 349 | 350 | 351 | true 352 | everyChunk 353 | 354 | 355 | 356 | true 357 | everyChunk 358 | 359 | 360 | 361 | true 362 | everyChunk 363 | 364 | 365 | 366 | true 367 | true 368 | 369 | 370 | 371 | true 372 | true 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | true 381 | true 382 | 10 ms 383 | 384 | 385 | 386 | true 387 | true 388 | 10 ms 389 | 390 | 391 | 392 | true 393 | true 394 | 10 ms 395 | 396 | 397 | 398 | true 399 | true 400 | 10 ms 401 | 402 | 403 | 404 | false 405 | true 406 | 407 | 408 | 409 | true 410 | true 411 | 412 | 413 | 414 | true 415 | 1000 ms 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | true 424 | 425 | 426 | 427 | true 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | true 436 | 437 | 438 | 439 | true 440 | 441 | 442 | 443 | 444 | 445 | -------------------------------------------------------------------------------- /projects/07_JFR_JavaFX/guimark.jfr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/projects/07_JFR_JavaFX/guimark.jfr -------------------------------------------------------------------------------- /projects/07_JFR_JavaFX/lib/GUIMark2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/projects/07_JFR_JavaFX/lib/GUIMark2.jar -------------------------------------------------------------------------------- /projects/08_JFR_Exceptions/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /projects/08_JFR_Exceptions/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | 08_JFR_Exceptions 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /projects/08_JFR_Exceptions/Launchers/ExceptionThrower Auto Record.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /projects/08_JFR_Exceptions/Launchers/ExceptionThrower.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /projects/08_JFR_Exceptions/Readme.txt: -------------------------------------------------------------------------------- 1 | This example shows how to record information about exceptions. 2 | 3 | 1. Run ExceptionTrower. 4 | 2. Record a flight recording with the Profiling with Exceptions template. 5 | 3. How many exceptions were thrown in the recording? 6 | 4. From where? 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 1. If using the incorrect recording template, no exception events will be recorded. 47 | 2. It is all in the Code | Exceptions tab. -------------------------------------------------------------------------------- /projects/08_JFR_Exceptions/exceptions.jfr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/projects/08_JFR_Exceptions/exceptions.jfr -------------------------------------------------------------------------------- /projects/08_JFR_Exceptions/src/se/hirt/jmc/tutorial/exceptions/ExceptionThrower.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Marcus Hirt 3 | * 4 | * jmc-tutorial is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * jmc-tutorial is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with jmc-tutorial. If not, see . 16 | */ 17 | package se.hirt.jmc.tutorial.exceptions; 18 | 19 | /** 20 | * Example which will throw two different kinds of exceptions. 21 | */ 22 | public final class ExceptionThrower implements Runnable { 23 | // The poor lab laptops will probably need one spare 24 | // hardware thread. 25 | private static final int THREADS = Runtime.getRuntime().availableProcessors() - 1; 26 | public long scaryCounter; 27 | 28 | public static void main(String[] args) throws Exception { 29 | System.out.println("Starting " + THREADS + " exception throwing threads!"); 30 | for (int i = 0; i < THREADS; i++) { 31 | Thread t = new Thread(new ExceptionThrower()); 32 | t.setDaemon(true); 33 | t.start(); 34 | } 35 | System.out.println("Press to quit!"); 36 | System.in.read(); 37 | } 38 | 39 | private void loop() { 40 | while (true) { 41 | try { 42 | doStuff(); 43 | } catch (Exception e) { 44 | // Evilly swallow the exception. 45 | } 46 | sleep(1); 47 | } 48 | } 49 | 50 | private void doStuff() throws Exception { 51 | // Having a few frames on the stack makes the traces, um, more interesting. 52 | if (isScary()) { 53 | doScaryThing(); 54 | } else { 55 | throwMe(); 56 | } 57 | } 58 | 59 | private void doScaryThing() throws ScaryException { 60 | throw new ScaryException("Really quite scary exception message!"); 61 | } 62 | 63 | private boolean isScary() { 64 | return ++scaryCounter % 10 == 0; 65 | } 66 | 67 | private void throwMe() throws ExceptionThrowerException { 68 | throw new ExceptionThrowerException("Just your average exception message."); 69 | } 70 | 71 | @Override 72 | public void run() { 73 | loop(); 74 | } 75 | 76 | private static void sleep(long ms) { 77 | try { 78 | Thread.sleep(ms); 79 | } catch (InterruptedException e) { 80 | e.printStackTrace(); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /projects/08_JFR_Exceptions/src/se/hirt/jmc/tutorial/exceptions/ExceptionThrowerException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Marcus Hirt 3 | * 4 | * jmc-tutorial is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * jmc-tutorial is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with jmc-tutorial. If not, see . 16 | */ 17 | package se.hirt.jmc.tutorial.exceptions; 18 | 19 | /** 20 | * One of the example exceptions being thrown. 21 | */ 22 | public class ExceptionThrowerException extends Exception { 23 | private static final long serialVersionUID = 1L; 24 | 25 | public ExceptionThrowerException(String message) { 26 | super(message); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /projects/08_JFR_Exceptions/src/se/hirt/jmc/tutorial/exceptions/ScaryException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Marcus Hirt 3 | * 4 | * jmc-tutorial is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * jmc-tutorial is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with jmc-tutorial. If not, see . 16 | */ 17 | package se.hirt.jmc.tutorial.exceptions; 18 | 19 | /** 20 | * Another example exceptions being thrown. 21 | */ 22 | public class ScaryException extends Exception { 23 | private static final long serialVersionUID = 1L; 24 | 25 | public ScaryException(String message) { 26 | super(message); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /projects/09_JFR_CustomEvents/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | 09_JFR_CustomEvents 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /projects/09_JFR_CustomEvents/fibonacci.jfr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/projects/09_JFR_CustomEvents/fibonacci.jfr -------------------------------------------------------------------------------- /projects/12_Console_LoadAndDeadlock/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /projects/12_Console_LoadAndDeadlock/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12_Console_LoadAndDeadlock 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /projects/12_Console_LoadAndDeadlock/Launchers/LoadAndDeadlock Auto Record.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /projects/12_Console_LoadAndDeadlock/Launchers/LoadAndDeadlock Continuous Example.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /projects/12_Console_LoadAndDeadlock/Launchers/LoadAndDeadlock Dump on Exit.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /projects/12_Console_LoadAndDeadlock/Launchers/LoadAndDeadlock Dynamic Enablement.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /projects/12_Console_LoadAndDeadlock/Launchers/LoadAndDeadlock NMT.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /projects/12_Console_LoadAndDeadlock/Launchers/LoadAndDeadlock Remote Access.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /projects/12_Console_LoadAndDeadlock/Launchers/LoadAndDeadlock.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /projects/12_Console_LoadAndDeadlock/Readme.txt: -------------------------------------------------------------------------------- 1 | This application shows off the Management Console. It's especially useful for 2 | building triggers on CPU load and for illustrating how deadlocked threads will 3 | show up in the Threads tab. 4 | 5 | 1. Can you build a rule that triggers and generates an alert? 6 | 2. What threads are deadlocked? Which thread is holding the lock that Thread-1 is waiting on? 7 | 8 | Tips below if you get stuck: 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 1. Triggers rules are built on the MBeans | Triggers tab. 49 | 50 | 2. The CPU load attribute is under oracle.jrockit.management/Runtime#CPULoad. 51 | 52 | 3. CPU load is in fractions, in other words 0.4 is 40%. 53 | 54 | 4. You need to enable the rule after creating it. 55 | 56 | 5. Deadlock detection is in the Runtime | Threads tab, and is enabled by checking the appropriate box. 57 | 58 | 6. You can sort on deadlocked threads by clicking the appropriate column header. 59 | 60 | 7. Deadlocked threads also have a different icon. 61 | 62 | 8. You can enable more columns, such as the _Lock Owner Name_, by clicking the table settings. 63 | 64 | -------------------------------------------------------------------------------- /projects/12_Console_LoadAndDeadlock/src/se/hirt/jmc/tutorial/console/LoadAndDeadlock.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Marcus Hirt 3 | * 4 | * jmc-tutorial is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * jmc-tutorial is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with jmc-tutorial. If not, see . 16 | */ 17 | package se.hirt.jmc.tutorial.console; 18 | 19 | import java.io.IOException; 20 | 21 | /** 22 | * Example which every once in a while will put a little load on the machine. It will also deadlock 23 | * two of the threads. 24 | */ 25 | public class LoadAndDeadlock { 26 | 27 | private static class AllocThread extends Thread { 28 | public void run() { 29 | while (true) { 30 | Thread.yield(); 31 | try { 32 | sleep(20 * 1000); 33 | } catch (Exception e) { 34 | } 35 | 36 | for (int i = 0; i < 40000; i++) { 37 | char[] tmp = new char[1024 * 1024]; 38 | tmp[1] = 'a'; 39 | } 40 | } 41 | } 42 | } 43 | 44 | private static class LockerThread extends Thread { 45 | Object l1; 46 | Object l2; 47 | 48 | public void init(Object lock1, Object lock2) { 49 | l1 = lock1; 50 | l2 = lock2; 51 | } 52 | 53 | public void run() { 54 | while (true) { 55 | synchronized (l1) { 56 | try { 57 | Thread.sleep(1000); 58 | } catch (InterruptedException e) { 59 | } 60 | synchronized (l2) { 61 | try { 62 | Thread.sleep(1000); 63 | } catch (InterruptedException e) { 64 | } 65 | System.out.println("Got one!"); 66 | } 67 | } 68 | } 69 | } 70 | 71 | } 72 | 73 | public static void main(String[] args) throws IOException { 74 | AllocThread allocthread = new AllocThread(); 75 | allocthread.setDaemon(true); 76 | Object lock1 = new Object(); 77 | Object lock2 = new Object(); 78 | 79 | LockerThread first = new LockerThread(); 80 | LockerThread second = new LockerThread(); 81 | first.setDaemon(true); 82 | second.setDaemon(true); 83 | 84 | first.init(lock1, lock2); 85 | second.init(lock2, lock1); 86 | 87 | allocthread.start(); 88 | first.start(); 89 | second.start(); 90 | 91 | System.out.print("Press enter to quit!"); 92 | System.out.flush(); 93 | System.in.read(); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /projects/13_JOverflow/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13_JOverflow 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /projects/13_JOverflow/eclipse.hprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/projects/13_JOverflow/eclipse.hprof -------------------------------------------------------------------------------- /projects/13_JOverflow/jmc41dump.hprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/projects/13_JOverflow/jmc41dump.hprof -------------------------------------------------------------------------------- /projects/Logs/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Logs 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /projects/Logs/log.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegreystone/jmc-tutorial/7c2aec08016363bd8d0a2d76f6dec584cdcdc217/projects/Logs/log.txt -------------------------------------------------------------------------------- /projects/Recordings/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Recordings 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | --------------------------------------------------------------------------------