<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Yousef Zook</title>
    <description>The latest articles on DEV Community by Yousef Zook (@yousef_zook).</description>
    <link>https://dev.to/yousef_zook</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F731480%2Fe630ec9c-06c6-4d7d-88d5-92b08dfb77cc.jpeg</url>
      <title>DEV Community: Yousef Zook</title>
      <link>https://dev.to/yousef_zook</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yousef_zook"/>
    <language>en</language>
    <item>
      <title>Java Performance - 5 - An introduction to Garbage Collection</title>
      <dc:creator>Yousef Zook</dc:creator>
      <pubDate>Fri, 03 Dec 2021 13:04:21 +0000</pubDate>
      <link>https://dev.to/yousef_zook/java-performance-5-an-introduction-to-garbage-collection-1d87</link>
      <guid>https://dev.to/yousef_zook/java-performance-5-an-introduction-to-garbage-collection-1d87</guid>
      <description>&lt;h2&gt;
  
  
  Recap
&lt;/h2&gt;

&lt;p&gt;Hello hello :3, welcom back. This is the part number 6 for the series &lt;code&gt;Java Performance&lt;/code&gt; that summarize the &lt;strong&gt;java performance book&lt;/strong&gt; by &lt;strong&gt;Scot Oaks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the previous chapter we have talked about the JIT compilers in Java, and introduced the new VM &lt;code&gt;GraalVM&lt;/code&gt;. We have also discussed some important tuning flags regarding the JIT and the tiered compilation.&lt;/p&gt;

&lt;p&gt;In this chapter we are going to talk about &lt;strong&gt;Garbage Collectors&lt;/strong&gt; in Java. We will mention breifely how they are working and the difference of performance between them. &lt;/p&gt;

&lt;p&gt;So, let's start the fifth chapter...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cpv4aq98--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://i.pinimg.com/originals/43/3d/83/433d83f7e481f35245f8c6bb7c7591d8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cpv4aq98--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://i.pinimg.com/originals/43/3d/83/433d83f7e481f35245f8c6bb7c7591d8.gif" alt="Intro" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Chapter Title:
&lt;/h2&gt;

&lt;p&gt;An Introduction to Garbage Collection&lt;/p&gt;

&lt;p&gt;Because the performance of Java applications depends heavily on garbage collection technology, it is not surprising that quite a few collectors are available. The OpenJDK has three collectors suitable for production, another that is deprecated in JDK 11 but still quite popular in JDK 8, and some experimental collectors that will (ideally) be production-ready in future releases. Other Java implementations such as Open J9 or the Azul JVM have their own collectors.&lt;/p&gt;

&lt;h2&gt;
  
  
  1) Garbage Collection Overview
&lt;/h2&gt;

&lt;p&gt;At a basic level, GC consists of finding objects that are in use and freeing the memory associated with the remaining objects (those that are not in use).&lt;/p&gt;

&lt;p&gt;Since references cannot be tracked dynamically via a count, instead, the JVM must peri‐ odically search the heap for unused objects.&lt;br&gt;
&lt;strong&gt;Why cannot be tracked by a count?!&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Answer:&lt;/em&gt; Consider this example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Given a linked list of objects, each object in the list (except the head) will be pointed to by another object in the list—but if nothing refers to the head of the list, the entire list is not in use and can be freed. And if the list is circular (e.g., the tail of the list points to the head), every object in the list has a reference to it—even though no object in the list can actually be used, since no objects reference the list itself.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GC main steps are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Freeing Objects&lt;/li&gt;
&lt;li&gt;Compaction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wjXhBq7f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dvnvj5c6a8rpre6fhlbu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wjXhBq7f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dvnvj5c6a8rpre6fhlbu.png" alt="Image description" width="880" height="518"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  A- Generational Garbage Collectors
&lt;/h3&gt;

&lt;p&gt;Though the details differ somewhat, most garbage collectors work by splitting the heap into generations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The old generation (or tenured)&lt;/li&gt;
&lt;li&gt;The young generation, this contains

&lt;ul&gt;
&lt;li&gt;eden&lt;/li&gt;
&lt;li&gt;survivor spaces&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Objects are first allocated in the &lt;code&gt;young generation&lt;/code&gt;, which is a subset of the entire heap. When the young generation fills up, the garbage collector will stop all the application threads and empty out the young generation. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Objects that are no longer in use are discarded, &lt;/li&gt;
&lt;li&gt;and objects that are still in use are moved elsewhere (survivor space, and if no available space in the survior then to the old generation). This operation is called a minor GC or a young GC.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This design has 2 performance advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;because the young generation is only a portion of the entire heap, processing it is faster than processing the entire heap. The application threads are stopped for a much shorter period of time than if the entire heap were processed at once.&lt;/li&gt;
&lt;li&gt;The second advantage arises from the way objects are allocated in the young genera‐ tion. Objects are allocated in eden (which encompasses the vast majority of the young generation). When the young generation is cleared during a collection, all objects in eden are either moved or discarded: objects that are not in use can be discarded, and objects in use are moved either to one of the survivor spaces or to the old generation. Since all surviving objects are moved, the young generation is automatically compacted when it is collected: at the end of the collection, eden and one of the survi‐ vor spaces are empty, and the objects that remain in the young generation are com‐ pacted within the other survivor space.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  B- GC Algorithms
&lt;/h3&gt;

&lt;p&gt;The following table lists the algorithms and their status in OpenJdk and Oracle Java releases:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QGmpSh5u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nli8r2dhu8k34eliw9qz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QGmpSh5u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nli8r2dhu8k34eliw9qz.png" alt="Image description" width="880" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1- The serial garbage collector&lt;/strong&gt;&lt;br&gt;
The serial collector uses a single thread to process the heap. It will stop all application threads as the heap is processed (for either a minor or full GC). During a full GC, it will fully compact the old generation.&lt;br&gt;
The serial collector is enabled by using the &lt;code&gt;-XX:+UseSerialGC&lt;/code&gt; flag &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2- The throughput collector&lt;/strong&gt;&lt;br&gt;
In JDK 8, the throughput collector is the default collector for any 64-bit machine with two or more CPUs. The throughput collector uses multiple threads to collect the young generation, which makes minor GCs much faster than when the serial collec‐ tor is used. This uses multiple threads to process the old generation as well. Because it uses multiple threads, the throughput collector is often called the parallel collector.&lt;br&gt;
The throughput collector stops all application threads during both minor and full GCs, and it fully compacts the old generation during a full GC. Since it is the default in most situations where it would be used, it needn’t be explicitly enabled. To enable it where necessary, use the flag &lt;code&gt;-XX:+UseParallelGC&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3- The G1 GC collector&lt;/strong&gt;&lt;br&gt;
The G1 GC (or garbage first garbage collector) uses a concurrent collection strategy to collect the heap with minimal pauses. It is the default collector in JDK 11 and later for 64-bit JVMs on machines with two or more CPUs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;G1 GC divides the heap into regions, but it still considers the heap to have two generations. Some of those regions make up the young generation, and the young genera‐ tion is still collected by stopping all application threads and moving all objects that are alive into the old generation or the survivor spaces. (This occurs using multiple threads.&lt;/li&gt;
&lt;li&gt;In G1 GC, the old generation is processed by background threads that don’t need to stop the application threads to perform most of their work. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;G1 GC is enabled by specifying the flag &lt;code&gt;-XX:+UseG1GC&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4- The CMS collector&lt;/strong&gt;&lt;br&gt;
The CMS collector was the first concurrent collector. Like other algorithms, CMS stops all application threads during a minor GC, which it performs with multiple threads.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CMS is officially deprecated in JDK 11 and beyond, and its use in JDK 8 is discouraged.&lt;/li&gt;
&lt;li&gt;the major flaw in CMS is that it has no way to compact the heap during its background processing. If the heap becomes fragmented (which is likely to happen at some point), CMS must stop all application threads and compact the heap, which defeats the purpose of a concurrent collector.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CMS is enabled by specifying the flag &lt;code&gt;-XX:+UseConcMarkSweepGC&lt;/code&gt;, which is false by default. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5- Experimental collectors&lt;/strong&gt;&lt;br&gt;
Garbage collection continues to be fertile ground for JVM engineers, and the latest versions of Java come with the three experimental algorithms mentioned earlier. I’ll have more to say about those in the next chapter; for now, let’s continue with a look at choosing among the three collectors supported in production environments.&lt;/p&gt;
&lt;h3&gt;
  
  
  C- Choosing a GC Algorithm
&lt;/h3&gt;

&lt;p&gt;The choice of a GC algorithm depends &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;in part on the hardware available.
&lt;/li&gt;
&lt;li&gt;in part on what the application looks like.
&lt;/li&gt;
&lt;li&gt;and in part on the performance goals for the application.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;When to use (and not use) the serial collector&lt;/strong&gt;&lt;br&gt;
On a machine with a single CPU, the JVM defaults to using the serial collector. This includes virtual machines with one CPU, and Docker containers that are limited to one CPU.&lt;/p&gt;

&lt;p&gt;In these environments, the serial collector is usually a good choice, but at times G1 GC will give better results. This example is also a good starting point for understand‐ ing the general trade-offs involved in choosing a GC algorithm.&lt;/p&gt;

&lt;p&gt;let's start by a CPU-intensive batch job:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8GYP7Ike--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2miwttxtc6t0n6apb4pk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8GYP7Ike--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2miwttxtc6t0n6apb4pk.png" alt="Image description" width="544" height="204"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;the serial collector wins because it spends much less time paused for garbage collection.&lt;/p&gt;

&lt;p&gt;Let's take another example, the following table shows the response time for a web server that is handling roughly 11 requests per second on its single CPU, which takes roughly 50% of the available CPU cycles.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JiU7Z6rm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cdejt2qkew5dx1zkjm92.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JiU7Z6rm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cdejt2qkew5dx1zkjm92.png" alt="Image description" width="880" height="176"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The default (serial) algorithm still has the best average time, by 30%. Again, that’s because the collections of the young generation by the serial collector are generally faster than those of the other algorithms, so an average request is delayed less by the serial collector.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When to use the throughput collecotr&lt;/strong&gt;&lt;br&gt;
When a machine has multiple CPUs available, more-complex interactions can occur between GC algorithms, but at a basic level, the trade-offs between G1 GC and the throughput collector are the same as we’ve just seen. For example, The follosing table shows how our sample application works when running either two or four application threads on a machine with four cores (where the cores are not hyper-threaded).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--a8StxEnh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ghe0sr0k2ywnmeid5yu4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--a8StxEnh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ghe0sr0k2ywnmeid5yu4.png" alt="Image description" width="680" height="162"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When the elapsed time of an application is key, the throughput collector will be advantageous when it spends less time pausing the application threads than G1 GC does. That happens when one or more of these things occur:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There are no (or few) full GCs. Full GC pauses can easily dominate the pause times of an application, but if they don’t occur in the first place, the throughput collector is no longer at a disadvantage.&lt;/li&gt;
&lt;li&gt;The old generation is generally full, causing the background G1 GC threads to work more.&lt;/li&gt;
&lt;li&gt;The G1 GC threads are starved for CPU.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's take another test. This test is the same code we used before for batch jobs with long calculations, though it has a few modifications: multiple applica‐ tion threads are doing calculations (two, in this case), the old generation is seeded with objects to keep it 65% full, and almost all objects can be collected directly from the young generation. This test is run on a system with four CPUs (not hyper- threaded) so that there is sufficient CPU for the G1 GC background threads to run.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BCvG9zuV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8tw4odu6ujvuiy3t084l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BCvG9zuV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8tw4odu6ujvuiy3t084l.png" alt="Image description" width="520" height="258"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  2) Basic GC Tuning
&lt;/h2&gt;

&lt;p&gt;Although GC algorithms differ in the way they process the heap, they share basic configuration parameters. In many cases, these basic configurations are all that is needed to run an application.&lt;br&gt;
There are 4 basic areas that can be tuned for better GC in java:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sizing the heap&lt;/li&gt;
&lt;li&gt;Sizing the generations &lt;/li&gt;
&lt;li&gt;Sizing Metaspace &lt;/li&gt;
&lt;li&gt;Controlling Parallelism&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  A- Sizing the Heap
&lt;/h3&gt;

&lt;p&gt;Like most performance issues, choosing a heap size is a matter of balance. If the heap is too small, the program will spend too much time performing GC and not enough time performing application logic. But simply specifying a very large heap isn’t neces‐ sarily the answer either. The time spent in GC pauses is dependent on the size of the heap, so as the size of the heap increases, the duration of those pauses also increases. The pauses will occur less frequently, but their duration will make the overall perfor‐ mance lag.&lt;/p&gt;

&lt;p&gt;The first rule in sizing a heap is never to specify a heap that is larger than the amount of physical memory on the machine and if multiple JVMs are running, that applies to the sum of all their heaps. &lt;/p&gt;

&lt;p&gt;The size of the heap is controlled by two values: an initial value (specified with &lt;code&gt;-XmsN&lt;/code&gt;) and a maximum value (&lt;code&gt;-XmxN&lt;/code&gt;). The defaults vary depending on the operating system, the amount of system RAM, and the JVM in use. The defaults can be affected by other flags on the command line as well; heap sizing is one of the JVM’s core ergonomic tunings.&lt;br&gt;
The following table shows the default heap sizes for differenct operating systems:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZblXevTx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jl3qqc03q0zx9ac8mo7v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZblXevTx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jl3qqc03q0zx9ac8mo7v.png" alt="Image description" width="880" height="257"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On a machine with less than 192 MB of physical memory, the maximum heap size will be half of the physical memory (96 MB or less).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  B- Sizing the Generations
&lt;/h3&gt;

&lt;p&gt;Once the heap size has been determined, the JVM must decide how much of the heap to allocate to the young generation and how much to allocate to the old generation.&lt;/p&gt;

&lt;p&gt;The command-line flags to tune the generation sizes all adjust the size of the young generation; the old generation gets everything that is left over. A variety of flags can be used to size the young generation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;-XX:NewRatio=N&lt;/strong&gt;
Set the ratio of the young generation to the old generation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;-XX:NewSize=N&lt;/strong&gt;
Set the initial size of the young generation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;-XX:MaxNewSize=N&lt;/strong&gt;
Set the maximum size of the young generation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;-XmnN&lt;/strong&gt;
Shorthand for setting both NewSize and MaxNewSize to the same value.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  C- Sizing Metaspace
&lt;/h3&gt;

&lt;p&gt;When the JVM loads classes, it must keep track of certain metadata about those classes. This occupies a separate heap space called the &lt;em&gt;metaspace&lt;/em&gt;. In older JVMs, this was handled by a different implementation called &lt;em&gt;permgen&lt;/em&gt;.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ebnD_rTD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a5gljb6x3gmnw0oto1xl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ebnD_rTD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a5gljb6x3gmnw0oto1xl.png" alt="Image description" width="754" height="266"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The metaspace behaves similarly to a separate instance of the regular heap. It is sized dynamically based on an initial size (&lt;code&gt;-XX:MetaspaceSize=N&lt;/code&gt;) and will increase as needed to a maximum size (&lt;code&gt;-XX:MaxMetaspaceSize=N&lt;/code&gt;). &lt;/p&gt;
&lt;h3&gt;
  
  
  D- Controlling Parallelism
&lt;/h3&gt;

&lt;p&gt;All GC algorithms except the serial collector use multiple threads. The number of these threads is controlled by the &lt;code&gt;-XX:ParallelGCThreads=N&lt;/code&gt; flag. The value of this flag affects the number of threads used for the following operations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Collection of the young generation when using &lt;code&gt;-XX:+UseParallelGC&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Collection of the old generation when using &lt;code&gt;-XX:+UseParallelGC&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Collection of the young generation when using &lt;code&gt;-XX:+UseG1GC&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Stop-the-world phases of G1 GC (though not full GCs)&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  3) GC Tools
&lt;/h2&gt;

&lt;p&gt;Since GC is central to the performance of Java, many tools monitor its performance. The best way to see the effect that GC has on the performance of an application is to become familiar with the GC log, which is a record of every GC operation during the program’s execution.&lt;/p&gt;
&lt;h3&gt;
  
  
  A- Enabling GC Logging in JDK 8
&lt;/h3&gt;

&lt;p&gt;JDK 8 provides multiple ways to enable the GC log. Specifying either of the flags &lt;code&gt;-verbose:gc&lt;/code&gt; or &lt;code&gt;-XX:+PrintGC&lt;/code&gt; will create a simple GC log (the flags are aliases for each other, and by default the log is disabled). The &lt;code&gt;-XX:+PrintGCDetails&lt;/code&gt; flag will create a log with much more information. &lt;strong&gt;This flag is recommended&lt;/strong&gt; (it is also false by default); it is often too difficult to diagnose what is happening with GC using only the simple log.&lt;/p&gt;
&lt;h3&gt;
  
  
  B- Enabling GC Logging in JDK 11
&lt;/h3&gt;

&lt;p&gt;JDK 11 and later versions use Java’s new unified logging feature. This means that all logging—GC related or not—is enabled via the flag &lt;code&gt;-Xlog&lt;/code&gt;.&lt;br&gt;
hen you append various options to that flag that control how the logging should be performed. In order to specify logging similar to the long example from JDK 8, you would use this flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-Xlog:gc*:file=gc.log:time:filecount=7,filesize=8M
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The colons divide the command into four sections. You can run java -Xlog:help: to get more information on the available options, but here’s how they map for this string.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One thing to note&lt;/strong&gt;: log rotation is handled slightly differently between JDK 8 and JDK 11. Say that we have specified a log name of &lt;code&gt;gc.log&lt;/code&gt; and that three files should be retained. &lt;br&gt;
&lt;strong&gt;In JDK 8&lt;/strong&gt;, the logs will be written this way:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start logging to gc.log.0.current.&lt;/li&gt;
&lt;li&gt;When full, rename that to gc.log.0 and start logging to gc.log.1.current.&lt;/li&gt;
&lt;li&gt;When full, rename that to gc.log.1 and start logging to gc.log.2.current.&lt;/li&gt;
&lt;li&gt;When full, rename that to gc.log.2, remove gc.log.0, and start logging to a new gc.log.0.current.&lt;/li&gt;
&lt;li&gt;Repeat this cycle.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;In JDK 11&lt;/strong&gt;, the logs will be written this way:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start logging to gc.log.&lt;/li&gt;
&lt;li&gt;When that is full, rename it to gc.log.0 and start a new gc.log.&lt;/li&gt;
&lt;li&gt;When that is full, rename it to gc.log.1 and start a new gc.log.&lt;/li&gt;
&lt;li&gt;When that is full, rename it to gc.log.2 and start a new gc.log.&lt;/li&gt;
&lt;li&gt;When that is full, rename it to gc.log.0, removing the old gc.log.0, and start a new gc.log.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For real-time monitoring of the heap, use &lt;code&gt;jvisualvm&lt;/code&gt; or &lt;code&gt;jconsole&lt;/code&gt;. The Memory panel of jconsole displays a real-time graph of the heap:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Wt5C_n1p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bx8cc6cljfktnd03k4uq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Wt5C_n1p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bx8cc6cljfktnd03k4uq.png" alt="Image description" width="880" height="607"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Aaaaaand that's it for today :D
&lt;/h2&gt;

&lt;h4&gt;
  
  
  🏃 See you in chapter 6 ...
&lt;/h4&gt;




&lt;h2&gt;
  
  
  🐒take a tip
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Keep your machine clean and tidy. : house:&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xpM3gUX3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://media4.giphy.com/media/NV4cSrRYXXwfUcYnua/200.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xpM3gUX3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://media4.giphy.com/media/NV4cSrRYXXwfUcYnua/200.gif" alt="Clean" width="356" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>performance</category>
      <category>java</category>
      <category>programming</category>
      <category>books</category>
    </item>
    <item>
      <title>Java Performance - 4 - Working with the JIT Compiler</title>
      <dc:creator>Yousef Zook</dc:creator>
      <pubDate>Sat, 13 Nov 2021 13:51:20 +0000</pubDate>
      <link>https://dev.to/yousef_zook/java-performance-4-working-with-the-jit-compiler-1ak4</link>
      <guid>https://dev.to/yousef_zook/java-performance-4-working-with-the-jit-compiler-1ak4</guid>
      <description>&lt;h2&gt;
  
  
  Recap
&lt;/h2&gt;

&lt;p&gt;This article is part 5 for the series &lt;code&gt;Java Performance&lt;/code&gt; that summarize the &lt;strong&gt;java performance book&lt;/strong&gt; by &lt;strong&gt;Scot Oaks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the previous chapter we have discussed performance toolbox in java. We have mentioned JVM commands to monitor cpu, network and disk usage. We have also talked about the JFR (Java Flight Recorder).&lt;/p&gt;

&lt;p&gt;In this chapter we are going to talk about how java is run on a computer and how it's converted into binary, we are also going to describe the difference between &lt;strong&gt;JIT&lt;/strong&gt; and &lt;strong&gt;AOT&lt;/strong&gt; compilers and some details about &lt;strong&gt;GraalVM&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Great, let's start the fourth chapter...&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.pinimg.com%2Foriginals%2F43%2F3d%2F83%2F433d83f7e481f35245f8c6bb7c7591d8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.pinimg.com%2Foriginals%2F43%2F3d%2F83%2F433d83f7e481f35245f8c6bb7c7591d8.gif" alt="Intro"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Chapter Title:
&lt;/h2&gt;

&lt;p&gt;Working with the JIT Compiler&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;just-in-time (JIT) compiler&lt;/em&gt; is the heart of the Java Virtual Machine; nothing controls the performance of your application more than the JIT compiler.&lt;/p&gt;
&lt;h2&gt;
  
  
  1) Just-in-Time Compilers: An Overview
&lt;/h2&gt;

&lt;p&gt;Computers CPUs can execute only a relatively few specific instructions, called &lt;em&gt;machine code&lt;/em&gt;.&lt;br&gt;
There are two types of programming languages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Compiled Languages&lt;/strong&gt; like C++ and Fortran. Their programs are derived as binary (machine) code ready to run on the cpu.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interpreted Languages&lt;/strong&gt; like PHP and perl. They are interpreted which means that the same program source code can be run on any CPU as long as the machine has the correct interpreter (that is, the program called php or perl). The interpreter translates each line of the program into binary code as that line is executed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each system has advantages and disadvantages. Programs written in interpreted languages are portable, however it is slower than compiled ones.&lt;/p&gt;
&lt;h3&gt;
  
  
  A- HotSpot Compilation
&lt;/h3&gt;

&lt;p&gt;As discussed in Chapter 1, the Java implementation discussed in this book is Oracle’s HotSpot JVM. This name (HotSpot) comes from the approach it takes toward compiling the code. &lt;/p&gt;

&lt;p&gt;It compile the java code to &lt;strong&gt;java bytecodes&lt;/strong&gt;, then starting at run time interpreting these bytecodes.&lt;/p&gt;

&lt;p&gt;when the JVM executes code, it does not begin compiling the code immediately. There are two basic reasons for this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;First:&lt;/strong&gt; if the code is going to be executed only once, then compiling it is essentially a wasted effort; it will be faster to interpret the Java bytecodes than to compile them and execute (only once) the compiled code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Second:&lt;/strong&gt; is the optimization reason, the more times that the JVM executes a particular method or loop, the more information it has about that code. This allows the JVM to make numerous optimizations when it compiles the code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;example:&lt;/strong&gt; consider the &lt;code&gt;equals()&lt;/code&gt; method. This method exists in every Java object (because it is inherited from the Object class) and is often overridden. When the interpreter encounters the statement &lt;code&gt;b = obj1.equals(obj2)&lt;/code&gt;, it must look up the type (class) of &lt;code&gt;obj1&lt;/code&gt; in order to know which &lt;code&gt;equals()&lt;/code&gt; method to execute. This dynamic lookup can be somewhat time-consuming.&lt;br&gt;&lt;br&gt;
Over time, say the JVM notices that each time this statement is executed, &lt;code&gt;obj1&lt;/code&gt; is of type &lt;code&gt;java.lang.String&lt;/code&gt;. Then the JVM can produce compiled code that directly calls the &lt;code&gt;String.equals()&lt;/code&gt; method. Now the code is faster not only because it is compiled but also because it can skip the lookup of which method to call.&lt;/p&gt;


&lt;h2&gt;
  
  
  2) Tiered Compilation
&lt;/h2&gt;

&lt;p&gt;Once upon a time, the JIT compiler came in two flavors, and you had to install different versions of the JDK depending on which compiler you wanted to use. These compilers are known as the &lt;strong&gt;client&lt;/strong&gt; (now called &lt;strong&gt;C1&lt;/strong&gt;) and &lt;strong&gt;server&lt;/strong&gt; (now called &lt;strong&gt;C2&lt;/strong&gt;) compilers. Today, all shipping JVMs include both compilers (though in common usage, they are usually referred to as server JVMs).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;C1&lt;/strong&gt;: begins compiling sooner, less aggressive in optimization but faster&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C2&lt;/strong&gt;: begins compiling later, after collecting some optimization informations while the code is running&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That technique is known as &lt;strong&gt;tiered compilation&lt;/strong&gt;, and it is the technique all JVMs now use. It can be explicitly disabled with the &lt;code&gt;-XX:TieredCompilation&lt;/code&gt; flag (the default value of which is true).&lt;/p&gt;


&lt;h2&gt;
  
  
  3) Common Compiler Flags
&lt;/h2&gt;

&lt;p&gt;Two commonly used flags affect the JIT compiler; we’ll look at them in this section.&lt;br&gt;
1- Code cache&lt;br&gt;
2- Inspection flag&lt;/p&gt;
&lt;h3&gt;
  
  
  A- Tuning the code cache
&lt;/h3&gt;

&lt;p&gt;When the JVM compiles code, it holds the set of assembly-language instructions in &lt;strong&gt;the code cache&lt;/strong&gt;. The code cache has a fixed size, and once it has filled up, the JVM is not able to compile any additional code.&lt;br&gt;
When the code cache fills up, the JVM spits out this warning:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    Java HotSpot(TM) 64-Bit Server VM warning: CodeCache is full. Compiler has been disabled.
    Java HotSpot(TM) 64-Bit Server VM warning: Try increasing the code cache size using -XX:ReservedCodeCacheSize=
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To solve the problem, a typical option is to simply double or quadruple the default.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The maximum size of the code cache is set via the &lt;code&gt;-XX:ReservedCodeCacheSize=N&lt;/code&gt; flag (where N is the default just mentioned for the particular compiler). &lt;/li&gt;
&lt;li&gt;there is an initial size (specified by &lt;code&gt;-XX:InitialCodeCacheSize=N&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The initial size of the code cache is 2,496 KB, and the default maximum size is 240 MB.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Resizing the cache happens in the background and doesn’t really affect performance, so setting the &lt;code&gt;ReservedCodeCacheSize&lt;/code&gt; size (i.e., setting the maximum code cache size) is all that is generally needed.&lt;/p&gt;

&lt;p&gt;In Java 11, the code cache is segmented into three parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nonmethod code&lt;/li&gt;
&lt;li&gt;Profiled code&lt;/li&gt;
&lt;li&gt;Nonprofiled code
By default, the code cache is sized the same way (up to 240 MB), and you can still adjust the total size of the code cache by using the ReservedCodeCacheSize flag.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You’ll rarely need to tune these segments individually, but if so, the flags are as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-XX:NonNMethodCodeHeapSize=N&lt;/code&gt; for the nonmethod code &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-XX:ProfiledCodeHapSize=N&lt;/code&gt; for the profiled code&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-XX:NonProfiledCodeHapSize=N&lt;/code&gt; for the nonprofiled code&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  B- Inspecting the Compilation Process
&lt;/h3&gt;

&lt;p&gt;The second flag isn’t a tuning per se: it will not improve the performance of an application. Rather, the &lt;code&gt;-XX:+PrintCompilation&lt;/code&gt; flag (which by default is false) gives us visibility into the workings of the compiler (though we’ll also look at tools that provide similar information).&lt;/p&gt;

&lt;p&gt;If PrintCompilation is enabled, every time a method (or loop) is compiled, the JVM prints out a line with information about what has just been compiled, with the following format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;timestamp  compilation_id  attributes  (tiered_level)  method_name  size  deopt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;timestamp&lt;/code&gt; here is the time after the compilation has finished (relative to 0, which is when the JVM started).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Compilation_id&lt;/code&gt; is an internal task ID. Sometimes you may see an out-of-order compilation ID. This happens most frequently when there are multiple compilation threads&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;attributes&lt;/code&gt;: it is a series of five characters that indicates the state of the code being compiled

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;%&lt;/code&gt; the compilation is OSR (on-stack replacement): JIT compilation is an asynchronous process: when the JVM decides that a certain method should be compiled, that method is placed in a queue. Rather than wait for the compilation, the JVM then continues interpreting the method, and the next time the method is called, the JVM will execute the compiled version of the method (assuming the compilation has finished, of course). &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;s&lt;/code&gt; The method is synchronized&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;!&lt;/code&gt; The method has an exception handler.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;b&lt;/code&gt; Compilation occurred in blocking mode: will never be printed by default in current versions of Java; it indicates that compilation did not occur in the background.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;n&lt;/code&gt; Compilation occurred for a wrapper to a native method: indicates that the JVM generated compiled code to facili‐ tate the call into a native method.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;tiered_level&lt;/code&gt; indicates which compiler (c1 levels vs c2 levels), If tiered compilation has been disabled, the next field (tiered_level) will be blank. Otherwise, it will be a number indicating which tier has completed compilation.&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;method_name&lt;/code&gt; the name of the compiled method&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;size&lt;/code&gt;  the size (in bytes) of the code being compiled.&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;deopt&lt;/code&gt; in some cases appears and indicates that some sort of deoptimization has occurred.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;The compilation log may also include a line that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    timestamp compile_id COMPILE SKIPPED: reason
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Code cache filled&lt;/em&gt;: The size of the code cache needs to be increased using the ReservedCodeCache flag.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Concurrent classloading&lt;/em&gt;: The class was modified as it was being compiled. The JVM will compile it again later; you should expect to see the method recompiled later in the log.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here are a few lines of output from enabling PrintCompilation on the stock REST application:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F927g7kvwdrj548686gvx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F927g7kvwdrj548686gvx.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The server took about 2 seconds to start; the remaining 26 seconds before anything else was compiled were essentially idle as the application server waited for requests.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;process()&lt;/code&gt; method is synchronized, so the attributes include an s.&lt;/li&gt;
&lt;li&gt;Inner classes are compiled just like any other class and appear in the output with the usual Java nomenclature: &lt;code&gt;outer-classname$inner-classname&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;processRequest()&lt;/code&gt; method shows up with the exception handler as expected.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  C- Tiered Compilation Levels
&lt;/h3&gt;

&lt;p&gt;The compilation log for a program using tiered compilation prints the tier level at which each method is compiled.&lt;br&gt;&lt;br&gt;
So the levels of compilation are as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;0&lt;/strong&gt;: Inerpreted code&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1&lt;/strong&gt;: Simple C1 compiled code&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2&lt;/strong&gt;: Limited C1 compiled code&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3&lt;/strong&gt;: Full C1 compiled code&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;4&lt;/strong&gt;: C2 compiled code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A typical compilation log shows that most methods are first compiled at level 3: full C1 compilation. (All methods start at level 0, of course, but that doesn’t appear in the log.) If a method runs often enough, it will get compiled at level 4 (and the level 3 code will be made not entrant). &lt;strong&gt;This is the most frequent path&lt;/strong&gt;: the C1 compiler waits to compile something until it has information about how the code is used that it can leverage to perform optimizations.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If the C2 compiler queue is full, methods will be pulled from the C2 queue and com‐ piled at level 2, which is the level at which the C1 compiler uses the invocation and back-edge counters (but doesn’t require profile feedback).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On the other hand, if the C1 compiler queue is full, a method that is scheduled for compilation at level 3 may become eligible for level 4 compilation while still waiting to be compiled at level 3. In that case, it is quickly compiled to level 2 and then transi‐ tioned to level 4.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Trivial methods may start in either level 2 or 3 but then go to level 1 because of their trivial nature. If the C2 compiler for some reason cannot compile the code, it will also go to level 1. And, of course, when code is deoptimized, it goes to level 0.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  D- Deoptimization
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Deoptimization&lt;/em&gt; means that the compiler has to “undo” a previous compilation. The effect is that the performance of the application will be reduced, at least until the compiler can recompile the code in question.&lt;/p&gt;

&lt;p&gt;Deoptimization occurs in two cases: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;when code is made not entrant: Two things cause code to be made not entrant:

&lt;ul&gt;
&lt;li&gt;One is due to the way classes and interfaces work, example: If an interface has two implementations, and compiler assumes that an implementation of an interface is called most of the time so decided to inline the code of the first implementation as optimization, then the second implementation has been called which means that the compiler assumption is not correct, then it need to do deoptimization.&lt;/li&gt;
&lt;li&gt;and one is an implementation detail of tiered compilation: When code is compiled by the C2 compiler, the JVM must replace the code already compiled by the C1 compiler.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;when code is made zombie: When the compilation log reports that it has made zombie code, it is saying that it has reclaimed previous code that was made not entrant. For performance, this is a good thing. Recall that the compiled code is held in a fixed- size code cache; when zombie methods are identified, the code in question can be removed from the code cache, making room for other classes to be compiled (or lim‐ iting the amount of memory the JVM will need to allocate later).&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  4) Advanced Compiler Flags
&lt;/h2&gt;
&lt;h3&gt;
  
  
  A- Compilation Thresholds
&lt;/h3&gt;

&lt;p&gt;This chapter has been somewhat vague in defining just what triggers the compilation of code. The major factor is how often the code is executed; once it is executed a cer‐ tain number of times, its compilation threshold is reached, and the compiler deems that it has enough information to compile the code.&lt;/p&gt;

&lt;p&gt;Compilation is based on two counters in the JVM: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the number of times the method has been called, - and the number of times any loops in the method have branched back.
&lt;strong&gt;Branching back&lt;/strong&gt; can effectively be thought of as the number of times a loop has completed execution, either because it reached the end of the loop itself or because it executed a branching statement like &lt;code&gt;continue&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When the JVM executes a Java method, it checks the sum of those two counters and decides whether the method is eligible for compilation. &lt;/p&gt;

&lt;p&gt;Tunings affect these thresholds. When tiered compilation is disabled, standard compilation is triggered by the value of the &lt;code&gt;-XX:CompileThreshold=N&lt;/code&gt; flag. The default value of N is &lt;code&gt;10,000&lt;/code&gt;. Changing the value of the CompileThreshold flag will cause the compiler to choose to compile the code sooner (or later) than it normally would have. Note, however, that although there is one flag here, the threshold is calculated by adding the sum of the back-edge loop counter plus the method entry counter.    &lt;/p&gt;

&lt;p&gt;changing the flags -XX:Tier3InvocationThreshold=N (default 200) to get C1 to compile a method more quickly, and -XX:Tier4InvocationThreshold=N (default 5000) to get C2 to compile a method more quickly. Similar flags are available for the back-edge threshold.&lt;/p&gt;
&lt;h3&gt;
  
  
  B- Compilation Threads
&lt;/h3&gt;

&lt;p&gt;when a method (or loop) becomes eligible for compilation, it is queued for compilation. That queue is processed by one or more background threads.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;These queues are not strictly first in, first out; methods whose invocation counters are higher have priority. &lt;/li&gt;
&lt;li&gt;The C1 and C2 compilers have different queues, each of which is processed by (potentially multiple) different threads.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following table shows default number of C1 and C2 compiler threads for tiered compilation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhm6kipxgwx8yyn37qbdi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhm6kipxgwx8yyn37qbdi.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If tiered compilation is disabled, only the given number of C2 compiler threads are started.&lt;/p&gt;
&lt;h3&gt;
  
  
  C- Inlining
&lt;/h3&gt;

&lt;p&gt;One of the most important optimizations the compiler makes is to inline methods. Code that follows good object-oriented design often contains attributes that are accessed via getters (and perhaps setters):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Point&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; 
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;getX&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setX&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The overhead for invoking a method call like this is quite high, especially relative to the amount of code in the method. &lt;/p&gt;

&lt;p&gt;Fortunately, JVMs now routinely perform code inlining for these kinds of methods. Hence, you can write this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Point&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getPoint&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setX&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getX&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The compiled code will essentially execute this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Point&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getPoint&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; 
&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inlining is enabled by default. It can be disabled using the &lt;code&gt;-XX:-Inline&lt;/code&gt; flag.&lt;/p&gt;

&lt;h3&gt;
  
  
  D- Escape Analysis
&lt;/h3&gt;

&lt;p&gt;The C2 compiler performs aggressive optimizations if escape analysis is enabled (&lt;code&gt;-XX:+DoEscapeAnalysis&lt;/code&gt;, which is true by default). For example, consider this class to work with factorials:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Factorial&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;BigInteger&lt;/span&gt; &lt;span class="n"&gt;factorial&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Factorial&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; 
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;synchronized&lt;/span&gt; &lt;span class="nc"&gt;BigInteger&lt;/span&gt; &lt;span class="nf"&gt;getFactorial&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; 
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;factorial&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;factorial&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;...;&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;factorial&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; 
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To store the first 100 factorial values in an array, this code would be used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BigInteger&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BigInteger&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;();&lt;/span&gt; 
&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inti&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++){&lt;/span&gt;
    &lt;span class="nc"&gt;Factorial&lt;/span&gt; &lt;span class="n"&gt;factorial&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Factorial&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;factorial&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getFactorial&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The factorial object is referenced only inside that loop; no other code can ever access that object. Hence, the JVM is free to perform optimizations on that object:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It needn’t get a &lt;code&gt;synchronization&lt;/code&gt; lock when calling the &lt;code&gt;getFactorial()&lt;/code&gt; method.&lt;/li&gt;
&lt;li&gt;It needn’t store the field n in memory; it can keep that value in a register. Similarly, it can store the factorial object reference in a register.&lt;/li&gt;
&lt;li&gt;In fact, it needn’t allocate an actual factorial object at all; it can just keep track of the individual fields of the object.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This kind of optimization is sophisticated: it is simple enough in this example, but these optimizations are possible even with more-complex code. &lt;/p&gt;




&lt;h2&gt;
  
  
  5) Tiered Compilation Trade-offs
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Question&lt;/strong&gt; Given the performance advantages it provides, is there ever a reason to turn tiered compilation off?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Answer&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One such reason might be when running in a memory-constrained environment.&lt;/li&gt;
&lt;li&gt;for example you may be running in a Docker container with a small memory limit or in a cloud virtual machine that just doesn’t have quite enough memory. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The below table shows the effect of tiered compilation on the code cache&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr1eto5l6ald9a4kt0yqs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr1eto5l6ald9a4kt0yqs.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The C1 compiler compiled about four times as many classes and predictably required about four times as much memory for the code cache. &lt;/p&gt;




&lt;h2&gt;
  
  
  6) The GraalVM
&lt;/h2&gt;

&lt;p&gt;The GraalVM is a new virtual machine. It provides a means to run Java code, of course, but also code from many other languages. This universal virtual machine can also run JavaScript, Python, Ruby, R, and traditional JVM bytecodes from Java and other languages that compile to JVM bytecodes (e.g., Scala, Kotlin, etc.). Graal comes in two editions: a full open source Community Edition (CE) and a commercial Enter‐ prise Edition (EE). Each edition has binaries that support either Java 8 or Java 11.&lt;/p&gt;

&lt;p&gt;The GraalVM has two important contributions to JVM performance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;First, an add- on technology allows the GraalVM to produce fully native binaries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Second, the GraalVM can run in a mode as a regular JVM, but it contains a new implementation of the C2 compiler. This compiler is written in Java (as opposed to the traditional C2 compiler, which is written in C++).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Within the JVM, using the GraalVM compiler is considered experimental, so to enable it, you need to supply these flags: &lt;code&gt;-XX:+UnlockExperimentalVMOptions&lt;/code&gt;, &lt;code&gt;-XX:+EnableJVMCI&lt;/code&gt;, and &lt;code&gt;-XX:+UseJVMCICompiler&lt;/code&gt;. The default for all those flags is false.&lt;/p&gt;

&lt;p&gt;The following table shows the perfroamcne of Graal Compiler:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9nt3t8dx5zrz6m04ww54.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9nt3t8dx5zrz6m04ww54.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  7) Precompilation
&lt;/h2&gt;

&lt;p&gt;We began this chapter by discussing the philosophy behind a just-in-time compiler. Although it has its advantages, code is still subject to a warm-up period before it exe‐ cutes. What if in our environment a traditional compiled model would work better: an embedded system without the extra memory the JIT requires, or a program that completes before having a chance to warm up?&lt;br&gt;
In this section, we’ll look at two experimental features that address that scenario. Ahead-of-time compilation is an experimental feature of the standard JDK 11, and the ability to produce a fully native binary is a feature of the Graal VM&lt;/p&gt;

&lt;h3&gt;
  
  
  A- Ahead-of-Time compilation AOT
&lt;/h3&gt;

&lt;p&gt;Ahead-of-time (AOT) compilation was first available in JDK 9 for Linux only, but in JDK 11 it is available on all platforms. From a performance standpoint, it is still a work in progress, but this section will give you a sneak peek at it.&lt;/p&gt;

&lt;p&gt;AOT compilation allows you to compile some (or all) of your application in advance of running it. This compiled code becomes a shared library that the JVM uses when starting the application. In theory, this means the JIT needn’t be involved, at least in the startup of your application: your code should initially run at least as well as the C1 compiled code without having to wait for that code to be compiled.&lt;/p&gt;

&lt;p&gt;In practice, it’s a little different: the startup time of the application is greatly affected by the size of the shared library (and hence the time to load that shared library into the JVM). That means a simple application like a “Hello, world” application won’t run any faster when you use AOT compilation (in fact, it may run slower depending on the choices made to precompile the shared library).&lt;/p&gt;

&lt;h3&gt;
  
  
  B- GraalVM Native Compilation
&lt;/h3&gt;

&lt;p&gt;AOT compilation was beneficial for relatively large programs but didn’t help (and could hinder) small, quick-running programs. That is because it’s still an experimen‐ tal feature and because its architecture has the JVM load the shared library.&lt;/p&gt;

&lt;p&gt;he GraalVM, on the other hand, can produce full native executables that run without the JVM. These executables are ideal for short-lived programs. If you ran the examples, you may have noticed references in some things (like ignored errors) to GraalVM classes: AOT compilation uses GraalVM as its foundation. This is an Early Adopter feature of the GraalVM; it can be used in production with the appropriate license but is not subject to warranty.&lt;/p&gt;

&lt;p&gt;Limitations also exist on which Java features can be used in a program compiled into native code. These limitations include the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dynamic class loading (e.g., by calling Class.forName()).&lt;/li&gt;
&lt;li&gt;Finalizers.&lt;/li&gt;
&lt;li&gt;The Java Security Manager.&lt;/li&gt;
&lt;li&gt;JMX and JVMTI (including JVMTI profiling).&lt;/li&gt;
&lt;li&gt;Use of reflection often requires special coding or configuration.&lt;/li&gt;
&lt;li&gt;Use of dynamic proxies often requires special configuration.&lt;/li&gt;
&lt;li&gt;Use of JNI requires special coding or configuration.&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  🏃 See you in chapter 5 ...
&lt;/h4&gt;




&lt;h2&gt;
  
  
  🐒take a tip
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Embrace your beliefes, but make yourself open for changes. 🌔&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthumbs.gfycat.com%2FThisOrderlyArchaeopteryx-size_restricted.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthumbs.gfycat.com%2FThisOrderlyArchaeopteryx-size_restricted.gif" alt="Embrace changes"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>programming</category>
      <category>books</category>
      <category>performance</category>
    </item>
    <item>
      <title>Java Performance - 3 - A java Performance Toolbox</title>
      <dc:creator>Yousef Zook</dc:creator>
      <pubDate>Fri, 05 Nov 2021 20:30:35 +0000</pubDate>
      <link>https://dev.to/yousef_zook/java-performance-3-a-java-performance-toolbox-iad</link>
      <guid>https://dev.to/yousef_zook/java-performance-3-a-java-performance-toolbox-iad</guid>
      <description>&lt;h2&gt;
  
  
  Recap
&lt;/h2&gt;

&lt;p&gt;This article is part 4 for the series &lt;code&gt;Java Performance&lt;/code&gt; that summarize the &lt;strong&gt;java performance book&lt;/strong&gt; by &lt;strong&gt;Scot Oaks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the previous chapter we have discussed performance testing methods. We have mentioned the difference between &lt;em&gt;Micorbenchmarks&lt;/em&gt;, &lt;em&gt;Macrobenchmarks&lt;/em&gt; and &lt;em&gt;Mesobecnhmars&lt;/em&gt;. We have also talked about the &lt;em&gt;responsetime&lt;/em&gt;, &lt;em&gt;throughput&lt;/em&gt; and &lt;em&gt;variability&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In this chapter we are going to discuss some intersting measurement tools for cpu, network and disk. We will understand the difference different profilers in java and talk a bit about JFR &lt;code&gt;Java Flight Recorder&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Great, let's start the third chapter...&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.pinimg.com%2Foriginals%2F43%2F3d%2F83%2F433d83f7e481f35245f8c6bb7c7591d8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.pinimg.com%2Foriginals%2F43%2F3d%2F83%2F433d83f7e481f35245f8c6bb7c7591d8.gif" alt="Intro"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Chapter Title:
&lt;/h2&gt;

&lt;p&gt;A java Performance Toolbox&lt;/p&gt;

&lt;p&gt;Performance analysis is all about visibility—knowing what is going on inside an application and in the application’s environment. Visibility is all about tools. And so performance tuning is all about tools.&lt;/p&gt;
&lt;h2&gt;
  
  
  1) Operating System Tools and Analysis
&lt;/h2&gt;

&lt;p&gt;The starting point for program analysis is not Java-specific at all: it is the basic set of monitoring tools that come with the operating system.&lt;br&gt;
We are going to see a quick look on operating system methods to take a look into the usage of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CPU --&amp;gt; &lt;strong&gt;vmstat&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Disk --&amp;gt; &lt;strong&gt;iostat&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Network --&amp;gt; &lt;strong&gt;nicstat&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  A- CPU Usage
&lt;/h3&gt;

&lt;p&gt;CPU usage is typically divided into two categories: user time and system time (Windows refers to this as privileged time). &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;User time&lt;/strong&gt; is the percentage of time the CPU is executing application code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;System Time&lt;/strong&gt; is the percentage of time the CPU is executing kernel code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Goal&lt;/strong&gt; is to maximize the cpu utilization.&lt;/p&gt;

&lt;p&gt;If you run &lt;em&gt;vmstat 1&lt;/em&gt; on your Linux desktop, you will get a series of lines (one every second) that look like this:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh3n9k6l8qqc8luyaz13c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh3n9k6l8qqc8luyaz13c.png" alt="vmstat"&gt;&lt;/a&gt;&lt;br&gt;
As you can find in the output:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each second has a &lt;code&gt;system time = 3%&lt;/code&gt; and &lt;code&gt;user time = 42%&lt;/code&gt; approximately.&lt;/li&gt;
&lt;li&gt;CPU total time [aka utilization] is 45%
This means that the cpu is idle for 55% of the time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The CPU can be idle for multiple reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The application might be blocked on a synchronization primitive and unable to execute until that lock is released.&lt;/li&gt;
&lt;li&gt;The application might be waiting for something, such as a response to come back from a call to the database.&lt;/li&gt;
&lt;li&gt;The application might have nothing to do.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These first two situations are always indicative of something that can be addressed. If contention on the lock can be reduced or the database can be tuned so that it sends the answer back more quickly, then the program will run faster, and the average CPU use of the application will go up (assuming, of course, that there isn’t another such issue that will continue to block the application).&lt;/p&gt;

&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Java and Single CPU:&lt;/strong&gt;&lt;br&gt;
If code is batch-style application, then the cpu will not be idle, because it has work to do always [if job is blocked for i/o or something, another batch can use the cpu .. etc]&lt;br&gt;
 ...&lt;br&gt;
&lt;strong&gt;Java and multi CPU:&lt;/strong&gt;&lt;br&gt;
The general idea is the same as in single cpu, however making sure individual threads are not blocked will drive the CPU higher.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;h5&gt;
  
  
  CPU Run Queue
&lt;/h5&gt;

&lt;p&gt;You can monitor the number of threads that can be run [aka not blocked]. Those threads are called to be in the &lt;code&gt;CPU Run Queue&lt;/code&gt;. You can find the length of the run queue in the previous image at the first column &lt;code&gt;procs r&lt;/code&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl9dzihocu8lnyzerf6tj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl9dzihocu8lnyzerf6tj.png" alt="vmstat queue length"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In linux: the number equals the number of currently running threads [those that are using the processors] and the others who are waiting for processors to use.&lt;/li&gt;
&lt;li&gt;In Windows: the number equals the number &lt;strong&gt;does NOT&lt;/strong&gt; count the currently running threads.
So the goal in linux is to make this queue length = the number of machine processors, and in windows to make it = 0.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  B- Disk Usage
&lt;/h3&gt;

&lt;p&gt;Monitoring disk usage has two important goals. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first pertains to the application itself: if the application is doing a lot of disk I/O, that I/O can easily become a bottleneck.&lt;/li&gt;
&lt;li&gt;The second reason is to monitor disk usage, even if the application is not expected to perform a significant amount of I/O—is to help monitor if the system is swapping.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can use &lt;strong&gt;iostat&lt;/strong&gt; command to monitor the disk, Let's see an example:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj79gysh4a1o1to61o3ji.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj79gysh4a1o1to61o3ji.png" alt="iostat"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This application is writing data to disk &lt;strong&gt;sda&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;w_await&lt;/strong&gt;: the time to service each I/O write &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;util&lt;/strong&gt;: the disk utilization&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Applications that write to disk can be bottlenecked both because they are writing data inefficiently (too little through‐ put) or because they are writing too much data (too much throughput).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  C- Network Usage
&lt;/h3&gt;

&lt;p&gt;If you are running an application that uses the network—for example, a REST server—you must monitor the network traffic as well.&lt;br&gt;
You can use &lt;strong&gt;nicstat&lt;/strong&gt; to monitor the network, it is not the default of the system but it's opensource with more features.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftg2ep7ex592fkv3vt9ht.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftg2ep7ex592fkv3vt9ht.png" alt="nicstat"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Applications that write to the network can be bottlenecked because they are writing data inefficiently (too little through‐ put) or because they are writing too much data (too much throughput).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  2) Java Monitoring Tools
&lt;/h2&gt;

&lt;p&gt;To gain insight into the JVM itself, Java monitoring tools are required. These tools come with the JDK:&lt;/p&gt;
&lt;h3&gt;
  
  
  A- JVM Commands
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;jcmd&lt;/strong&gt;: Prints basic class, thread, and JVM information for a Java process.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;jconsole&lt;/strong&gt;: Provides a graphical view of JVM activities, including thread usage, class usage, and GC activities&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;jmap&lt;/strong&gt;: Provides heap dumps and other information about JVM memory usage. Suitable for scripting, though the heap dumps must be used in a postprocessing tool.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;jinfo&lt;/strong&gt;: Provides visibility into the system properties of the JVM, and allows some system properties to be set dynamically. Suitable for scripting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;jstack&lt;/strong&gt;: Dumps the stacks of a Java process. Suitable for scripting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;jstat&lt;/strong&gt;: Provides information about GC and class-loading activities. Suitable for scripting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;jvisualvm&lt;/strong&gt;: A GUI tool to monitor a JVM, profile a running application, and analyze JVM heap dumps (which is a postprocessing activity, though jvisualvm can also take the heap dump from a live program).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;if you are using docker, you can run them using &lt;code&gt;docker exec&lt;/code&gt; except &lt;code&gt;jconsole&lt;/code&gt; and &lt;code&gt;jvisualvm&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;These tools fits into these broad areas:&lt;br&gt;
• Basic VM information&lt;br&gt;
• Thread information&lt;br&gt;
• Class information&lt;br&gt;
• Live GC analysis&lt;br&gt;
• Heap dump postprocessing&lt;br&gt;
• Profiling a JVM&lt;/p&gt;
&lt;h3&gt;
  
  
  B- Basic VM Information
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Uptime
The length of time the JVM has been up can be found via this command:
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;% jcmd process_id VM.uptime&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;System properties
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;% jcmd process_id VM.system_properties&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;% jinfo -sysprops process_id&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JVM version
The version of the JVM is obtained like this:
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;% jcmd process_id VM.version&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JVM tuning flags
The tuning flags in effect for an application can be obtained like this:
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;% jcmd process_id VM.flags [-all]&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; you can change tuning flags dynamically at runtime using &lt;strong&gt;jinfo&lt;/strong&gt; command, example:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;% jinfo -flag -PrintGCDetails process_id # turns off PrintGCDetails &lt;br&gt;
% jinfo -flag PrintGCDetails process_id&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  3) Profiling Tools
&lt;/h2&gt;

&lt;p&gt;Profilers are the most important tool in a performance analyst’s toolbox. Many profil‐ ers are available for Java, each with its own advantages and disadvantages. &lt;/p&gt;

&lt;p&gt;Many common Java profiling tools are themselves written in Java and work by “attaching” themselves to the application to be profiled. This attachment is via a socket or via a native Java interface called the &lt;strong&gt;JVM Tool Interface&lt;/strong&gt; (JVMTI). &lt;br&gt;
This means you must pay attention to tuning the profiling tool just as you would tune any other Java application. In particular, if the application being profiled is large, it can transfer quite a lot of data to the profiling tool, so the profiling tool must have a sufficiently large heap to handle the data.&lt;/p&gt;

&lt;p&gt;Profiling happens in one of two modes: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sampling mode &lt;/li&gt;
&lt;li&gt;instrumented mode&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  A- Sampling Profilers
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;:The basic mode of profiling and carries the least amount of overhead. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;: However, sampling profilers can be subject to all sorts of errors, for example, the most common sampling erro is as shown in the figure below:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyriakcv0dnlfr21tg0y3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyriakcv0dnlfr21tg0y3.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
The thread here is alternating between executing methodA (shown in the shaded bars) and methodB (shown in the clear bars). If the timer fires only when the thread happens to be in methodB, the profile will report that the thread spent all its time executing methodB; in reality, more time was actually spent in methodA.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reason&lt;/strong&gt;: this is due to &lt;code&gt;safepoint bias&lt;/code&gt;, which means that the profiler can get the stack trace of a thread only when the thread is at safepoint, when they are:&lt;br&gt;
• Blocked on a synchronized lock&lt;br&gt;
• Blocked waiting for I/O&lt;br&gt;
• Blocked waiting for a monitor&lt;br&gt;
• Parked&lt;br&gt;
• Executing Java Native Interface (JNI) code (unless they perform a GC locking function)&lt;/p&gt;
&lt;h3&gt;
  
  
  B- Instrumented Profilers
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;: Instrumented profilers are much more intrusive than sampling profilers, but they can also give more beneficial information about what’s happening inside a program.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;: They are much more likely to introduce performance differences into the application than are sampling profilers.&lt;/p&gt;

&lt;p&gt;Instrumented profilers work by altering the bytecode sequence of classes as they are loaded (inserting code to count the invocations, and so on).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; &lt;/p&gt;

&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Is this a better profile than the sampled version? It depends; there is no way to know in a given situation which is the more accurate profile. The invocation count of an instrumented profile is certainly accurate, and that additional information is often helpful in determining where the code is spending more time and which things are more fruitful to optimize.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  C- Native Profilers
&lt;/h3&gt;

&lt;p&gt;Tools like async-profiler and Oracle Developer Studio have the capability to profile native code in addition to Java code. This has two advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;significant operations occur in native code, including within native libraries and native memory allocation.&lt;/li&gt;
&lt;li&gt;we typically profile to find bottlenecks in application code, but sometimes the native code is unexpectedly dominating performance. We would prefer to find out our code is spending too much time in GC by examining GC logs.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  4) Java Flight Recorder &lt;code&gt;JFR&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Java Flight Recorder (JFR) is a feature of the JVM that performs lightweight performance analysis of applications while they are running. As its name suggests, JFR data is a history of events in the JVM that can be used to diagnose the past performance and operations of the JVM.&lt;/p&gt;

&lt;p&gt;The basic operation of JFR is that a set of events is enabled (for example, one event is that a thread is blocked waiting for a lock), and each time a selected event occurs, data about that event is saved (either in memory or to a file). &lt;/p&gt;

&lt;p&gt;The higher the number of events, the higher the performance got affected by the JFR.&lt;/p&gt;
&lt;h3&gt;
  
  
  A- Java Mission Control
&lt;/h3&gt;

&lt;p&gt;The usual tool to examine JFR recordings is &lt;code&gt;Java Mission Control&lt;/code&gt; (jmc), though other tools exist, and you can use toolkits to write your own analysis tools.&lt;br&gt;
The Java Mission Control program (jmc) starts a window that displays the JVM pro‐ cesses on the machine and lets you select one or more processes to monitor. Figure 3-9 shows the Java Management Extensions (JMX) console of Java Mission Control monitoring our example REST server.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk8xq8jb44g1cjj42mj3k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk8xq8jb44g1cjj42mj3k.png" alt="JMC"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  B- JFR features
&lt;/h3&gt;

&lt;p&gt;The following table shows what other tools can collect and what jfr collects for each event:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Event&lt;/th&gt;
&lt;th&gt;Other tools&lt;/th&gt;
&lt;th&gt;JFR&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Classloading&lt;/td&gt;
&lt;td&gt;Number of classes loaded and unloaded&lt;/td&gt;
&lt;td&gt;Which classloader loaded the class; time required to load an individual class&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Thread statistics&lt;/td&gt;
&lt;td&gt;Number of threads created and destroyed; thread dumps&lt;/td&gt;
&lt;td&gt;Which threads are blocked on locks (and the specific lock they are blocked on)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Throwables&lt;/td&gt;
&lt;td&gt;Throwable classes used by the application&lt;/td&gt;
&lt;td&gt;Number of exceptions and errors thrown and the stack trace of their creation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TLAB allocation&lt;/td&gt;
&lt;td&gt;Number of allocations in the heap and size of thread-local allocation buffers (TLABs)&lt;/td&gt;
&lt;td&gt;Specific objects allocated in the heap and the stack trace where they are allocated&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File and socket I/O&lt;/td&gt;
&lt;td&gt;Time spent performing I/O&lt;/td&gt;
&lt;td&gt;Time spent per read/write call, the specific file or socket taking a long time to read or write&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monitor blocked&lt;/td&gt;
&lt;td&gt;Threads waiting for a monitor&lt;/td&gt;
&lt;td&gt;Specific threads blocked on specific monitors and the length of time they are blocked&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Code cache&lt;/td&gt;
&lt;td&gt;Size of code cache and how much it contains&lt;/td&gt;
&lt;td&gt;Methods removed from the code cache; code cache configuration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Code compilation&lt;/td&gt;
&lt;td&gt;Which methods are compiled, on-stack replacement (OSR) compilation, and length of time to compile&lt;/td&gt;
&lt;td&gt;Nothing specific to JFR, but unifies information from several sources&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Garbage collection&lt;/td&gt;
&lt;td&gt;Times for GC, including individual phases; sizes of generations&lt;/td&gt;
&lt;td&gt;Nothing specific to JFR, but unifies the information from several tools&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Profiling&lt;/td&gt;
&lt;td&gt;Instrumenting and sampling profiles&lt;/td&gt;
&lt;td&gt;Not as much as you’d get from a true profiler, but the JFR profile provides a good high-order overview&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  C- Enabling JFR
&lt;/h3&gt;

&lt;p&gt;JFR is initially disabled. To enable it, add the flag &lt;br&gt;
&lt;code&gt;-XX:+FlightRecorder&lt;/code&gt; to the command line of the application. This enables JFR as a feature, but no recordings will be made until the recording process itself is enabled. That can occur either through a GUI or via the command line.&lt;/p&gt;

&lt;p&gt;In Oracle’s JDK 8, you must also specify this flag (prior to the FlightRecorder flag): &lt;code&gt;-XX:+UnlockCommercialFeatures&lt;/code&gt; (default: false).&lt;br&gt;
If you forget to include these flags, remember that you can use &lt;code&gt;jinfo&lt;/code&gt; to change their values and enable JFR. If you use jmc to start a recording, it will automatically change these values in the target JVM if necessary.&lt;/p&gt;

&lt;p&gt;To enable it from command line:&lt;br&gt;
&lt;code&gt;-XX:+FlightRecorderOptions=string&lt;/code&gt;&lt;br&gt;
The string in that parameter is a list of comma-separated name- value pairs taken from these options:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name=name
--&amp;gt;The name used to identify the recording.
defaultrecording=&amp;lt;true|false&amp;gt;
--&amp;gt;Whether to start the recording initially. The default value is false; for reactive analysis, this should be set to true.
settings=path
--&amp;gt;Name of the file containing the JFR settings (see the next section).
delay=time
--&amp;gt;The amount of time (e.g., 30s, 1h) before the recording should start.
duration=time
--&amp;gt;The amount of time to make the recording.
filename=path
--&amp;gt;Name of the file to write the recording to.
compress=&amp;lt;true|false&amp;gt;
--&amp;gt;Whether to compress (with gzip) the recording; the default is false.
maxage=time
--&amp;gt;Maximum time to keep recorded data in the circular buffer.
maxsize=size
--&amp;gt;Maximum size (e.g., 1024K, 1M) of the recording’s circular buffer.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  🏃 See you in chapter 4 ...
&lt;/h4&gt;




&lt;h2&gt;
  
  
  🐒take a tip
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Never trust your code. 👮&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fc.tenor.com%2F4WZm1vgS_-8AAAAM%2Fthe-simpsons-homer-simpson.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fc.tenor.com%2F4WZm1vgS_-8AAAAM%2Fthe-simpsons-homer-simpson.gif" alt="Suspect your code"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>books</category>
      <category>java</category>
      <category>programming</category>
      <category>performance</category>
    </item>
    <item>
      <title>Java Performance - 2 -  An Approach to Performance Testing</title>
      <dc:creator>Yousef Zook</dc:creator>
      <pubDate>Sat, 30 Oct 2021 18:06:12 +0000</pubDate>
      <link>https://dev.to/yousef_zook/java-performance-chapter-2-1m10</link>
      <guid>https://dev.to/yousef_zook/java-performance-chapter-2-1m10</guid>
      <description>&lt;h1&gt;
  
  
  Recap
&lt;/h1&gt;

&lt;p&gt;This article is part 3 for the series &lt;code&gt;Java Performance&lt;/code&gt; that summarize the &lt;strong&gt;java performance book&lt;/strong&gt; by &lt;strong&gt;Scot Oaks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the previous chapter we have discussed a breif outline, the platforms, hardware and software, and perfromance hints &lt;code&gt;The Complete Performance Story&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In this chapter we are going to discuss some intersting performance entries. We will understand the difference between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Microbenchmarks&lt;/li&gt;
&lt;li&gt;Macrobenchmarks&lt;/li&gt;
&lt;li&gt;Mesobenchmarks
We are going also to talk about response time, batching and throughput, understand variability and see some interesting code examples.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Great, let's start the second chapter...&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.pinimg.com%2Foriginals%2F43%2F3d%2F83%2F433d83f7e481f35245f8c6bb7c7591d8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.pinimg.com%2Foriginals%2F43%2F3d%2F83%2F433d83f7e481f35245f8c6bb7c7591d8.gif" alt="Intro"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Chapter Title:
&lt;/h1&gt;

&lt;p&gt;An Approach to Performance Testing&lt;/p&gt;

&lt;h1&gt;
  
  
  1) Test a Real Application
&lt;/h1&gt;

&lt;p&gt;The first principle is that testing should occur on the actual product in the way the product will be used. There are, roughly speaking, three categories of code that can be used for performance testing, each with its own advantages and disadvantages. The category that includes the actual application will provide the best results.&lt;/p&gt;

&lt;h3&gt;
  
  
  A- Microbenchmarks
&lt;/h3&gt;

&lt;p&gt;The first of these categories is the microbenchmark. A microbenchmark is a test designed to measure a very small unit of performance, exmples: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The time to call a synchronized method versus a nonsynchronized method&lt;/li&gt;
&lt;li&gt;The overhead in creating a thread versus using a thread pool&lt;/li&gt;
&lt;li&gt;The time to execute one arithmetic algorithm versus an alternate implementation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Points to take care of&lt;/strong&gt;&lt;br&gt;
Consider the following code that measures the performance of different implementations of a method to compute the 50th Fibonacci number:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;doTest&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// Main Loop&lt;/span&gt;
    &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;then&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inti&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;nLoops&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++){&lt;/span&gt; 
       &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fibImpl1&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; 
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Elapsed time: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;then&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;fibImpl1&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Must be &amp;gt; 0"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fibImpl1&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;fibImpl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Double&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isInfinite&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArithmeticException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Overflow"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; 
&lt;span class="o"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The previous code has the following issues:&lt;br&gt;
1- &lt;strong&gt;Microbenchmarks must use their results&lt;/strong&gt;: The biggest problem with this code is that it never actually changes any program state. Because the result of the Fibonacci calculation is never used, the compiler is free to discard that calculation. A smart compiler will end using the following code:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;then&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Elapsed time: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;then&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt;: because you have never used the &lt;code&gt;l&lt;/code&gt; variable in your code, so the compiler will assume that this is a redundant code, removing it before executing.&lt;br&gt;
&lt;strong&gt;Solution&lt;/strong&gt; try to consume the l variable with any method you like.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;consume&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;2- &lt;strong&gt;Microbenchmarks must not include extraneous operations&lt;/strong&gt;: This code performs only one operation: calculating the 50th Fibonacci number. A very smart compiler can figure that out and execute the loop only once—or at least discard some of the iterations of the loop since those oper‐ ations are redundant.&lt;br&gt;
Additionally, the performance of fibImpl(1000) is likely to be very different than the performance of fibImpl(1); if the goal is to compare the performance of different im‐ plementations, then a range of input values must be considered.&lt;br&gt;
The easy way to code the use of the random number generator is to process the loop as follows:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;nLoops&lt;/span&gt;&lt;span class="o"&gt;];&lt;/span&gt; 
&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inti&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;nLoops&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++){&lt;/span&gt;
    &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nextInt&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;then&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inti&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;nLoops&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++){&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fibImpl1&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;]);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;IllegalArgumentException&lt;/span&gt; &lt;span class="n"&gt;iae&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt; 
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;3- &lt;strong&gt;Microbenchmarks must measure the correct input&lt;/strong&gt;: The third pitfall here is the input range of the test: selecting arbitrary random values isn’t necessarily representative of how the code will be used. In this case, an exception will be immediately thrown on half of the calls to the method under test (anything with a negative value). An exception will also be thrown anytime the input parameter is greater than 1476, since that is the largest Fibonacci number that can be represented in a double.&lt;br&gt;
Consider this alternate implementation:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;fibImplSlow&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Must be &amp;gt; 0"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; 
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1476&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArithmeticException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Must be &amp;lt; 1476"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; 
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;verySlowImpl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If that this implementation is very slow "solwer that the first one in point #2", It will give better perforamnce results because the input range checks in it &lt;code&gt;lines 1, and 2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;4- &lt;strong&gt;No warmup period&lt;/strong&gt;: The previous implementation doesn't offer a &lt;em&gt;warm-up peroid&lt;/em&gt; which is important because that One of the performance characteristics of Java is that code performs better the more it is executed, a topic that is covered in &lt;code&gt;Chapter 4&lt;/code&gt;, something realted to the JIT compilers in java.&lt;br&gt;
So the final version of the performance test should be as the following:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;net.sdo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Random&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FibonacciTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; 
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;volatile&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;nLoops&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; 
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;FibonacciTest&lt;/span&gt; &lt;span class="n"&gt;ft&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;                 
        &lt;span class="nc"&gt;FibonacciTest&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parseInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]));&lt;/span&gt; 
        &lt;span class="n"&gt;ft&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;doTest&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;ft&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;doTest&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;FibonacciTest&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; 
        &lt;span class="n"&gt;nLoops&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;nLoops&lt;/span&gt;&lt;span class="o"&gt;];&lt;/span&gt;
        &lt;span class="nc"&gt;Random&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Random&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; 
        &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inti&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;nLoops&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++){&lt;/span&gt;
            &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nextInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;doTest&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;isWarmup&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; 
        &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;then&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; 
        &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inti&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;nLoops&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++){&lt;/span&gt;
            &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fibImpl1&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;]);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;isWarmup&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; 
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Elapsed time: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;then&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; 
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;fibImpl1&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; 
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Must be &amp;gt; 0"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fibImpl1&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;fibImpl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Double&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isInfinite&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArithmeticException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Overflow"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; 
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; 
&lt;span class="o"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  B- Macrobenchmarks
&lt;/h3&gt;

&lt;p&gt;The best thing to use to measure performance of an application is the application itself, in conjunction with any external resources it uses. Testing the whole application with all the external resources is called &lt;strong&gt;Macrobenchmark&lt;/strong&gt;.&lt;br&gt;
Complex systems are more than the sum of their parts; they will behave quite differently when those parts are assembled. Mocking out database calls, for example, may mean that you no longer have to worry about the database perfor‐ mance—and hey, you’re a Java person; why should you have to deal with someone else’s performance problem?&lt;br&gt;
&lt;strong&gt;The other reason to test the full application&lt;/strong&gt; is one of resource allocation. In a perfect world, there would be enough time to optimize every line of code in the application. In the real world, deadlines loom, and optimizing only one part of a complex environment may not yield immediate benefits.&lt;/p&gt;
&lt;h3&gt;
  
  
  C- Mesobenchmarks
&lt;/h3&gt;

&lt;p&gt;Java EE engineers tend to use that term to apply to something else: bench‐ marks that measure one aspect of performance, but that still execute a lot of code.&lt;br&gt;
&lt;strong&gt;An example&lt;/strong&gt; of a Java EE might be something that measures how quickly the response from a simple JSP can be returned from an application server. The code involved in such a request is substantial compared to a traditional microbenchmark: there is a lot of socket-management code, code to read the request, code to find (and possibly compile) the JSP, code to write the answer, and so on. From a traditional standpoint, this is not microbenchmarking.&lt;br&gt;
This kind of test is not a macrobenchmark either: there is no security (e.g., the user does not log in to the application), no session management, and no use of a host of other Java EE features.&lt;br&gt;
So this is called a &lt;strong&gt;Mesobenchmark&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Common Code Examples
&lt;/h3&gt;

&lt;p&gt;Many of the examples throughout the book are based on a sample application that calculates the “historical” high and low price of a stock over a range of dates, as well as the standard deviation during that time. Historical is in quotes here because in the application, all the data is fictional; the prices and the stock symbols are randomly generated.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The basic object within the application is a StockPrice object&lt;/strong&gt; that represents the price range of a stock on a given day:
```java
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;public interface StockPrice { &lt;br&gt;
    String getSymbol();&lt;br&gt;
    Date getDate();&lt;br&gt;
    BigDecimal getClosingPrice();&lt;br&gt;
    BigDecimal getHigh();&lt;br&gt;
    BigDecimal getLow();&lt;br&gt;
    BigDecimal getOpeningPrice();&lt;br&gt;
    boolean isYearHigh();&lt;br&gt;
    boolean isYearLow();&lt;br&gt;
    Collection&amp;lt;? extends StockOptionPrice&amp;gt; getOptions();&lt;br&gt;
}&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The sample applications typically deal with a collection of these prices, representing the history of the stock over a period of time (e.g., 1 year or 25 years, depending on the example):
```java


public interface StockPriceHistory { 
    StockPrice getPrice(Date d);
    Collection&amp;lt;StockPrice&amp;gt; getPrices(Date startDate, Date endDate);
    Map&amp;lt;Date, StockPrice&amp;gt; getAllEntries();
    Map&amp;lt;BigDecimal,ArrayList&amp;lt;Date&amp;gt;&amp;gt; getHistogram();
    BigDecimal getAveragePrice();
    Date getFirstDate();
    BigDecimal getHighPrice();
    Date getLastDate();
    BigDecimal getLowPrice();
    BigDecimal getStdDev();
    String getSymbol();
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The basic implementation of this class loads a set of prices from the database:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StockPriceHistoryImpl&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;StockPriceHistory&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; 
    &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;StockPriceHistoryImpl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt; &lt;span class="n"&gt;startDate&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt; &lt;span class="n"&gt;endDate&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;EntityManager&lt;/span&gt; &lt;span class="n"&gt;em&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Date&lt;/span&gt; &lt;span class="n"&gt;curDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;startDate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getTime&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt; 
        &lt;span class="n"&gt;symbol&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;curDate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;after&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;endDate&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;StockPriceImpl&lt;/span&gt; &lt;span class="n"&gt;sp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;em&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;find&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;StockPriceImpl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StockPricePK&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;curDate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;clone&lt;/span&gt;&lt;span class="o"&gt;()));&lt;/span&gt; 
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sp&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="nc"&gt;Date&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;curDate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;clone&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; 
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;firstDate&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;firstDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
                &lt;span class="o"&gt;}&lt;/span&gt;
                &lt;span class="n"&gt;prices&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sp&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;lastDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="n"&gt;curDate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setTime&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;curDate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getTime&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;msPerDay&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt; 
&lt;span class="o"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The architecture of the samples is designed to be loaded from a database, and that functionality will be used in the examples in Chapter 11. However, to facilitate running the examples, most of the time they will use a mock entity manager that generates random data for the series.&lt;/p&gt;




&lt;h1&gt;
  
  
  2) Understand Throughput, Batching, and Response Time
&lt;/h1&gt;

&lt;p&gt;The second principle in performance testing involves various ways to look at the ap‐ plication’s performance. Which one to measure depends on which factors are most important to your application.&lt;/p&gt;

&lt;h3&gt;
  
  
  A- Elapsed Time (Batch) Measurements:
&lt;/h3&gt;

&lt;p&gt;The simplest way of measuring performance is to see &lt;strong&gt;how long it takes to accomplish a certain task&lt;/strong&gt;, example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Retrieve the history of 10,000 stocks for a 25-year period and calculate the standard deviation of those prices; produce a report of the payroll benefits for the 50,000 employees of a corporation; execute a loop 1,000,000 times.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the non-Java world, this testing is straightforward: the application is written, and the time of its execution is measured. In the Java world, there is one wrinkle to this: &lt;code&gt;just-in-time compilation&lt;/code&gt; which means that the program needs some time to be fully optimized [that's why we needed the warmup in the previous section code].&lt;/p&gt;

&lt;h3&gt;
  
  
  B- Throughput Measurements:
&lt;/h3&gt;

&lt;p&gt;A throughput measurement is based on &lt;strong&gt;the amount of work that can be accomplished in a certain period of time&lt;/strong&gt;. &lt;br&gt;
Notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In a client-server test, a throughput measurement means that clients have no think time. If there is a single client, that client sends a request to the server. When it receives a response, it immediately sends a new request.&lt;/li&gt;
&lt;li&gt;This measurement is frequently referred to as transactions per second (&lt;strong&gt;TPS&lt;/strong&gt;), requests per second (&lt;strong&gt;RPS&lt;/strong&gt;), or operations per second (&lt;strong&gt;OPS&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;All client-server tests run the risk that the client cannot send data quickly enough to the server. This may occur because there aren’t enough CPU cycles on the client machine to run the desired number of client threads, or because the client has to spend a lot of time processing the request before it can send a new request. In those cases, the test is effectively measuring the client performance rather than the server performance, which is usually not the goal.&lt;/li&gt;
&lt;li&gt;It is common for tests that measure throughput also to report the average response time of its requests.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  C- Response Time Tests
&lt;/h3&gt;

&lt;p&gt;The last common test is one that measures response time: &lt;strong&gt;the amount of time that elapses between the sending of a request from a client and the receipt of the response&lt;/strong&gt;.&lt;br&gt;
Difference between response time and throughput is that the client threads in a response time test sleep for some period of time between operations. This is referred to as &lt;em&gt;think time&lt;/em&gt;.&lt;br&gt;
When think time is introduced into a test, throughput becomes fixed: a given number of clients executing requests with a given think time will always yield the same TPS.&lt;br&gt;
&lt;strong&gt;example&lt;/strong&gt;:&lt;br&gt;
The simplest way is for clients to sleep for a period of time between requests:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;done&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;executeOperation&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;                 
    &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentThread&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;sleep&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In this case, the throughput is somewhat dependent on the response time. &lt;br&gt;
There is another alternative is known as &lt;em&gt;cycle time&lt;/em&gt; (rather than &lt;em&gt;think time&lt;/em&gt;). Cycle time sets the total time between requests to 30 seconds, so that the time the client sleeps depends on the response time:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;done&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;executeOperation&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; 
    &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentThread&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;sleep&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This alternative yields &lt;strong&gt;a fixed throughput of 0.033 OPS&lt;/strong&gt; per client regardless of the re‐ sponse time (assuming the response time is always less than 30 seconds in this example).&lt;/p&gt;

&lt;p&gt;There are &lt;strong&gt;two ways of measuring response time&lt;/strong&gt;. Response time can be reported as: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Average&lt;/strong&gt;: the individual times are added together and divided by the number of requests. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Percentile request&lt;/strong&gt;: for example the 90th% response time. If 90% of responses are less than 1.5 seconds and 10% of responses are greater than 1.5 seconds, then 1.5 seconds is the 90th% response time.
The following 2 graphs shows how the percentile is important:
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm6f7qo06l1xbx7z2rwgo.png" alt="Normal"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdogr1g7c2q957da8bpzh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdogr1g7c2q957da8bpzh.png" alt="Outilers"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  3) Understand Variability
&lt;/h1&gt;

&lt;p&gt;The third principle involves understanding &lt;strong&gt;how test results vary over time&lt;/strong&gt;. Programs that process exactly the same set of data will produce a different answer each time they are run. Why? because of the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Background processes on the machine will affect the application&lt;/li&gt;
&lt;li&gt;the network will be more or less congested when the program is run&lt;/li&gt;
&lt;li&gt;... etc.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You must consider statstics while measuring performance of an application, run the test many times to be more confident of your results.&lt;/p&gt;




&lt;h1&gt;
  
  
  4) Test Early, Test Often
&lt;/h1&gt;

&lt;p&gt;Fourth and finally, performance geeks like to recommend that perfor‐ mance testing be an integral part of the development cycle.&lt;br&gt;&lt;br&gt;
The typical development cycle does not make things any easier. A project schedule often establishes a feature-freeze date: all feature changes to code must be checked into the repository at some early point in the release cycle, and the remainder of the cycle is devoted to shaking out any bugs (including performance issues) in the new release. This causes two problems for early testing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Developers are under time constraints to get code checked in to meet the schedule; they will balk at having to spend time fixing a performance issue when the schedule has time for that after all the initial code is checked in. The developer who checks in code causing a 1% regression early in the cycle will face pressure to fix that issue; the developer who waits until the evening of the feature freeze can check in code that causes a 20% regression and deal with it later.&lt;/li&gt;
&lt;li&gt;Performance characteristics of code will change as the code changes. This is the same principle that argued for testing the full application (in addition to any module-level tests that may occur): heap usage will change, code compilation will change, and so on.&lt;/li&gt;
&lt;li&gt;A developer who introduces code causing a 5% regression may have a plan to address that regression as development proceeds: maybe her code depends on some as-yet-to-be integrated feature, and when that feature is available, a small tweak will allow the regression to go away. That’s a reasonable position, even though it means that performance tests will have to live with that 5% regression for a few weeks (and the unfortunate but unavoidable issue that said regression is masking other regressions).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Early, frequent testing is most useful if the following guidelines are followed:&lt;/p&gt;

&lt;h3&gt;
  
  
  A- Automate everything
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;All performance testing should be scripted&lt;/li&gt;
&lt;li&gt;The scripts must be able to run the test multiple times&lt;/li&gt;
&lt;li&gt;Perform t-test analysis on the results&lt;/li&gt;
&lt;li&gt;Produce a report showing the confidence level that the results are the same&lt;/li&gt;
&lt;li&gt;The automation must make sure that the machine is in a known state before tests are run&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  B- Measure everything
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The automation must gather every conceivable piece of data that will be useful for later analysis&lt;/li&gt;
&lt;li&gt;System information sampled throughout the run: CPU usage, disk usage, network usage, memory usage, and so on.&lt;/li&gt;
&lt;li&gt;The monitoring information must also include data from other parts of the system, if applicable: for example, if the program uses a database, then include the system statistics from the database machine as well as any diagnostic output from the database&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  C- Run on the target system
&lt;/h3&gt;

&lt;p&gt;A test that is run on a single-core laptop will behave very differently than a test run on a machine with a 256-thread SPARC CPU. That should be clear in terms of threading effects: the larger machine is going to run more threads at the same time, reducing contention among application threads for access to the CPU. At the same time, the large system will show synchronization bottlenecks that would be unno‐ ticed on the small laptop.&lt;br&gt;
Hence, the performance of a particular production environment can never be fully known without testing the expected load on the expected hardware. Approxima‐ tions and extrapolations can be made from running smaller tests on smaller hard‐ ware, and in the real world, duplicating a production environment for testing can be quite difficult or expensive.&lt;/p&gt;




&lt;h4&gt;
  
  
  🏃 See you in chapter 3 ...
&lt;/h4&gt;




&lt;h1&gt;
  
  
  🐒take a tip
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Play a sport to work your brain effectively, Exercise your body. 🏊&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia1.giphy.com%2Fmedia%2FxT5LMUQRajYE0HNab6%2Fgiphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia1.giphy.com%2Fmedia%2FxT5LMUQRajYE0HNab6%2Fgiphy.gif" alt="Sport"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>books</category>
      <category>java</category>
      <category>programming</category>
      <category>performance</category>
    </item>
    <item>
      <title>Java Performance - 1 - Introduction</title>
      <dc:creator>Yousef Zook</dc:creator>
      <pubDate>Sat, 23 Oct 2021 20:37:37 +0000</pubDate>
      <link>https://dev.to/yousef_zook/java-performance-chapter-1-1ocn</link>
      <guid>https://dev.to/yousef_zook/java-performance-chapter-1-1ocn</guid>
      <description>&lt;h1&gt;
  
  
  Recap
&lt;/h1&gt;

&lt;p&gt;In the previous article, we demonstrated that we are going to discuss the great book &lt;strong&gt;Java Performance 2&lt;/strong&gt;&lt;sup&gt;&lt;strong&gt;nd&lt;/strong&gt;&lt;/sup&gt; &lt;strong&gt;Edition&lt;/strong&gt; by Scott Oaks.&lt;br&gt;
In this article we are goind to summarize the first book chapter, &lt;em&gt;Chapter 1: Introduction&lt;/em&gt;.&lt;br&gt;
Please note that many senteces have been quoted from the book itself.&lt;br&gt;
While you are reading this article, please consider that you are reading a summarized version of the chapter and chapter bold points only are included.&lt;/p&gt;

&lt;p&gt;Great, let's start the first chapter...&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cpv4aq98--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://i.pinimg.com/originals/43/3d/83/433d83f7e481f35245f8c6bb7c7591d8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cpv4aq98--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://i.pinimg.com/originals/43/3d/83/433d83f7e481f35245f8c6bb7c7591d8.gif" alt="Intro" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Chapter Title:
&lt;/h1&gt;

&lt;p&gt;Introduction&lt;/p&gt;
&lt;h1&gt;
  
  
  For who?
&lt;/h1&gt;

&lt;p&gt;This book is designed for performance engineers and developers who are looking to understand how various aspects of the JVM and the Java APIs impact performance.&lt;br&gt;
If it is late Sunday night, your site is going live Monday morning, and you’re looking for a quick fix for performance issues, this is not the book for you.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;This is a book about the art and science of Java performance.&lt;/code&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Java Platforms
&lt;/h1&gt;

&lt;p&gt;The book has covered the performance of &lt;em&gt;Oracle Hotspot JVM&lt;/em&gt; and &lt;em&gt;Java Developement Kit&lt;/em&gt; &lt;code&gt;JDK&lt;/code&gt; version 8 and 11, This is also known as Java, Standard Edition (SE). &lt;br&gt;
These versions of the JDK were selected because they carry long-term support (LTS) from Oracle. &lt;/p&gt;
&lt;h3&gt;
  
  
  JVM tuning flags
&lt;/h3&gt;

&lt;p&gt;JVM flags are curical parameters that you can pass to the java virtual machine to enhance the performance of your application.&lt;br&gt;
With a few exceptions, the JVM accepts two kinds of flags: boolean flags, and flags that require a parameter.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Boolean flags&lt;/strong&gt; use this syntax: &lt;code&gt;-XX:+FlagName&lt;/code&gt; enables the flag, and &lt;code&gt;-XX:-FlagName&lt;/code&gt; disables the flag.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Paramterized Flags&lt;/strong&gt; that require a parameter use this syntax: &lt;code&gt;-XX:FlagName=something&lt;/code&gt;, meaning to set the value of &lt;code&gt;FlagName&lt;/code&gt; to &lt;code&gt;something&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8Jkg02I_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2jchpxqc171ej83y2hph.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8Jkg02I_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2jchpxqc171ej83y2hph.png" alt="Tuning Flags" width="880" height="522"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;from jrebel.com&lt;/em&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Hardware Platforms
&lt;/h1&gt;

&lt;p&gt;From a performance perspective, the important thing about a machine is its number of cores. Let’s take a basic four-core machine: each core can (for the most part) pro‐ cess independently of the others, so a machine with four cores can achieve four times the throughput of a machine with a single core. (This depends on other factors about the software, of course.)&lt;br&gt;
However adding more threads to this machine not necessirly increase throuput or make the program finishes quicker, will see more examples in the following chapters.&lt;/p&gt;
&lt;h3&gt;
  
  
  Software Containers
&lt;/h3&gt;

&lt;p&gt;The biggest change in Java deployments in recent years is that they are now fre‐ quently deployed within a software container. That change is not limited to Java, of course; it’s an industry trend hastened by the move to cloud computing.&lt;br&gt;
Two containers are important here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Virtual Machine: which sets up a com‐ pletely isolated copy of the operating system on a subset of the hardware on which the virtual machine is running. From Java’s perspective (and the perspective of other applications), that virtual machine is indistinguishable from a regular machine with &lt;code&gt;x cores&lt;/code&gt; and &lt;code&gt;n GB&lt;/code&gt; of memory.&lt;/li&gt;
&lt;li&gt;Docker Containers: A Java process running inside a Docker container doesn’t necessarily know it is in such a container. The Docker container is just a process (potentially with resource constraints) within a running OS, the way Java handles that differs between early versions of Java 8 (up until update 192) and later version of Java 8 (and all versions of Java 11).&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;
  
  
  The Complete Performance Story
&lt;/h1&gt;

&lt;p&gt;This book is focused on how to best use the JVM and Java platform APIs so that programs run faster, but many outside influences affect performance. &lt;br&gt;
Here are some notes for these outsides...&lt;/p&gt;
&lt;h3&gt;
  
  
  1.Write Better Algorithms:
&lt;/h3&gt;

&lt;p&gt;Ultimately, the performance of an application is based on how well it is written. If the program loops through all elements in an array, the JVM will optimize the way it per‐ forms bounds checking of the array so that the loop runs faster, and it may unroll the loop operations to provide an additional speedup. But if the purpose of the loop is to find a specific item, no optimization in the world is going to make the array-based code as fast as a different version that uses a hash map.&lt;/p&gt;
&lt;h3&gt;
  
  
  2.Write Less Code
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;A small well-written program will run faster than a large well-written program.   &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So even if your code should be neat, extensible and easy to read, you should also consider the performance while writing your code.&lt;br&gt;
A subset of the team may argue that they are adding a small piece of code which will not affect the perfromance, then another part calims the same, and after some repition you will find that the progress may be affected by 10%.&lt;br&gt;
Over time, as the small regressions creep in, it will be harder and harder to fix them.&lt;/p&gt;
&lt;h3&gt;
  
  
  3.Oh, Go Ahead, Prematurely Optimize
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;premature optimization&lt;/em&gt;: A term often used by developers to claim that the performance of their code doesn’t matter, and if it does matter, we won’t know that until the code is run.&lt;br&gt;
&lt;strong&gt;Notes:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you are going to change the code to get better performance but this will lead to complicating the code and make it hard to fix in the future, then it's better to not do this enhancement till the profiling is done and points that this enhancement is mandatory.&lt;/li&gt;
&lt;li&gt;However, if you have 2 choices and they are both straighforward and easy to make, and 1 of them will enhance the performance, then do it. 
Let's take the following example:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;log&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Level&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FINE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"I am here, and the value of X is "&lt;/span&gt;
            &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;calcX&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" and Y is "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;calcY&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This code do string concatination and calls some functions &lt;code&gt;calcX()&lt;/code&gt; and &lt;code&gt;calcY()&lt;/code&gt;, when the log level is &lt;code&gt;FINE&lt;/code&gt;. However this level of logging often are not used and it will not be printed, in this case it is better to check if it is loggable first to save the time of string concatination and the functions calls:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isLoggable&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Level&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FINE&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; 
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;log&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Level&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FINE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"I am here, and the value of X is {} and Y is {}"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
            &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;[]{&lt;/span&gt;&lt;span class="n"&gt;calcX&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;calcY&lt;/span&gt;&lt;span class="o"&gt;()});&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This avoids the string concatenation altogether (the message format isn’t necessarily more efficient, but it is cleaner), and there are no method calls or allocation of the object array unless logging has been enabled&lt;/p&gt;

&lt;h3&gt;
  
  
  4.Look Elsewhere: The Database Is Always the Bottleneck
&lt;/h3&gt;

&lt;p&gt;If you are developing standalone Java applications that use no external resources, the performance of that application is (mostly) all that matters. Once an external resource (a database, for example) is added, the performance of both programs is important. And in a distributed environment—say with a Java REST server, a load balancer, a database, and a backend enterprise information system—the performance of the Java server may be the least of the performance issues.&lt;br&gt;
If the database is the bottleneck, tuning the Java application accessing the database won’t help overall performance at all. In fact, it might be counterproductive. &lt;strong&gt;As a general rule&lt;/strong&gt;, &lt;code&gt;when load is increased into a system that is overburdened, performance of that system gets worse.&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5.Optimize for the Common Case
&lt;/h3&gt;

&lt;p&gt;we should focus on the common use case scenarios. This principle manifests itself in several ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Optimize code by profiling it and focusing on the operations in the profile taking the most time. &lt;/li&gt;
&lt;li&gt;Apply &lt;a href="https://en.wikipedia.org/wiki/Occam's_razor"&gt;Occam’s razor&lt;/a&gt; to diagnosing performance problems. The simplest explana‐ tion for a performance issue is the most conceivable cause: a performance bug in new code is more likely than a configuration issue on a machine, which in turn is more likely than a bug in the JVM or operating system.&lt;/li&gt;
&lt;li&gt;Write simple algorithms for the most common operations in an application&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  🏃 See you in chapter 2 ...
&lt;/h4&gt;




&lt;h1&gt;
  
  
  🐒take a tip
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Pareto principle: 80% of consequences come from 20% of causes.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ARfChr3a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://streetfins.com/wp-content/uploads/2021/03/7c-Pareto-Principle-1150x647-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ARfChr3a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://streetfins.com/wp-content/uploads/2021/03/7c-Pareto-Principle-1150x647-1.png" alt="Rule" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>books</category>
      <category>java</category>
      <category>performance</category>
    </item>
    <item>
      <title>Java Performance - Overview</title>
      <dc:creator>Yousef Zook</dc:creator>
      <pubDate>Wed, 20 Oct 2021 21:03:31 +0000</pubDate>
      <link>https://dev.to/yousef_zook/java-performance-summary-45d3</link>
      <guid>https://dev.to/yousef_zook/java-performance-summary-45d3</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia3.giphy.com%2Fmedia%2FZO8EB8aWJjXH6fRHxq%2Fgiphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia3.giphy.com%2Fmedia%2FZO8EB8aWJjXH6fRHxq%2Fgiphy.gif" alt="Performance"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  What is this?
&lt;/h1&gt;

&lt;p&gt;In this articles Series, I am going to summarize the main points of the incredible book "Java Perfroamcne" by Scott Oaks. &lt;br&gt;
This is a great book if you are interested in optimizing your java application and/or want to dig deeper into how java works and how to benchmark and profile your java applicatoin.&lt;br&gt;
We are going to discuss each chapter in a separate part of the article. &lt;br&gt;
This article is for people who want to take a quick summary for the book and/or want to get quick information of how to think in java performance without the need to read all the book.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2zrojajcq9flpnkr2zzz.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2zrojajcq9flpnkr2zzz.jpeg" alt="Book cover"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h1&gt;
  
  
  About Scott, the author
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Scott Oaks&lt;/strong&gt; is a Java Technologist at Sun Microsystems, where he has worked since 1987. While at Sun, he has specialized in many disparate technologies, from the SunOS kernel to network programming and RPCs. Since 1995, he's focused primarily on Java and bringing Java technology to end-users. Scott also authored O'Reilly's &lt;code&gt;Java Security&lt;/code&gt;, &lt;code&gt;Java Threads&lt;/code&gt; and &lt;code&gt;Jini in a Nutshell&lt;/code&gt; titles.&lt;br&gt;
&lt;em&gt;&lt;a href="https://www.oreilly.com/pub/au/193#:~:text=Scott%20Oaks%20is%20a%20Java,Java%20technology%20to%20end%2Dusers." rel="noopener noreferrer"&gt;Oreilly&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h1&gt;
  
  
  About the book
&lt;/h1&gt;

&lt;p&gt;We are going to disucss the 2nd edition of the book. This edition was published in Feburary 2020. The book index is as follow:&lt;/p&gt;

&lt;h3&gt;
  
  
  Table of Contents
&lt;/h3&gt;

&lt;p&gt;Let's see the index of the book highlights:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Introduction&lt;/strong&gt;

&lt;ol&gt;
&lt;li&gt;A breif Outline&lt;/li&gt;
&lt;li&gt;Platformas and Conventions&lt;/li&gt;
&lt;li&gt;The Complete Performance Story&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An approach to performance testing&lt;/strong&gt;

&lt;ol&gt;
&lt;li&gt;Test a Real Application&lt;/li&gt;
&lt;li&gt;Understand Throughput, Batching, and Response Time&lt;/li&gt;
&lt;li&gt;Understand Variablitiy&lt;/li&gt;
&lt;li&gt;Test Early, Test Often&lt;/li&gt;
&lt;li&gt;Benchmark Examples&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A Java Performance Toolbox&lt;/strong&gt;

&lt;ol&gt;
&lt;li&gt;Operating System Tools and Analysis&lt;/li&gt;
&lt;li&gt;Java Monitoring tools&lt;/li&gt;
&lt;li&gt;Profiling Tools&lt;/li&gt;
&lt;li&gt;Java Flight Recorder&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Working with the JIT Compiler&lt;/strong&gt;

&lt;ol&gt;
&lt;li&gt;JIT Overview&lt;/li&gt;
&lt;li&gt;Tiered Compilation&lt;/li&gt;
&lt;li&gt;Common Compiler Flags&lt;/li&gt;
&lt;li&gt;Advanced Compiler Flags&lt;/li&gt;
&lt;li&gt;The Compilation Trade-offs&lt;/li&gt;
&lt;li&gt;The GrallVM&lt;/li&gt;
&lt;li&gt;Precompilation&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An Introduction to Garbage Collection&lt;/strong&gt;

&lt;ol&gt;
&lt;li&gt;Garbage Collection Overview&lt;/li&gt;
&lt;li&gt;Basic GC Tuning&lt;/li&gt;
&lt;li&gt;GC Tools&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Garbage Collection Algorithms&lt;/strong&gt;

&lt;ol&gt;
&lt;li&gt;Understanding the Throughput Collector&lt;/li&gt;
&lt;li&gt;Understanding the G1 Garbage Collector&lt;/li&gt;
&lt;li&gt;Understanding the CMS Collector&lt;/li&gt;
&lt;li&gt;Advanced Tuning&lt;/li&gt;
&lt;li&gt;Experimental GC Algorithms&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Heap Memory Best Practices&lt;/strong&gt;

&lt;ol&gt;
&lt;li&gt;Heap Analysis&lt;/li&gt;
&lt;li&gt;Using Less Memory&lt;/li&gt;
&lt;li&gt;Object Life-Cycle Management&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Native Memory Best Practices&lt;/strong&gt;

&lt;ol&gt;
&lt;li&gt;Footprint&lt;/li&gt;
&lt;li&gt;JVM Tunings for the Operating System&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Threading and Synchronization Performance&lt;/strong&gt;

&lt;ol&gt;
&lt;li&gt;Threading and Hardware&lt;/li&gt;
&lt;li&gt;Thread Pools and ThreadPoolExectures&lt;/li&gt;
&lt;li&gt;The ForkJoinPool&lt;/li&gt;
&lt;li&gt;Thread Synchronization&lt;/li&gt;
&lt;li&gt;JVM Thread Tunings&lt;/li&gt;
&lt;li&gt;Monitoring Threads and Locks&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Java Servers&lt;/strong&gt;

&lt;ol&gt;
&lt;li&gt;Java NIO Overview&lt;/li&gt;
&lt;li&gt;Server Containers&lt;/li&gt;
&lt;li&gt;Asynchronous Outbound Calls&lt;/li&gt;
&lt;li&gt;Json Processing&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database Performance Best Practices&lt;/strong&gt;

&lt;ol&gt;
&lt;li&gt;Sample Database&lt;/li&gt;
&lt;li&gt;JDBC&lt;/li&gt;
&lt;li&gt;JPA&lt;/li&gt;
&lt;li&gt;Spring Data&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Java SE API Tips&lt;/strong&gt;

&lt;ol&gt;
&lt;li&gt;Strings&lt;/li&gt;
&lt;li&gt;Buffered I/O&lt;/li&gt;
&lt;li&gt;Classloading&lt;/li&gt;
&lt;li&gt;Random Numbers&lt;/li&gt;
&lt;li&gt;Java Native Interface&lt;/li&gt;
&lt;li&gt;Exceptions&lt;/li&gt;
&lt;li&gt;Logging&lt;/li&gt;
&lt;li&gt;Java Collections API&lt;/li&gt;
&lt;li&gt;Lambdas and Anonymous Classes&lt;/li&gt;
&lt;li&gt;Stream and Filter Performance&lt;/li&gt;
&lt;li&gt;Object Serilaization&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h1&gt;
  
  
  ✋Further notes
&lt;/h1&gt;

&lt;p&gt;I want to mention that I am adding each chapter after finishing reading it, so it may take sometime till finishing the 12 chapters in the article.&lt;br&gt;
If you have any suggestions and/or notes please mention them to enhance the article.&lt;/p&gt;

&lt;p&gt;As soon as I wrote a chapter, I will update this article to include it as a following part.&lt;br&gt;
see you there...&lt;/p&gt;




&lt;h1&gt;
  
  
  🐒take a tip
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Work smart &lt;strong&gt;AND&lt;/strong&gt; hard&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fc.tenor.com%2F2PnUyS0_ad0AAAAM%2Fsmart-thinking.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fc.tenor.com%2F2PnUyS0_ad0AAAAM%2Fsmart-thinking.gif" alt="working-smart"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fc.tenor.com%2FRlo-1wvJ_BgAAAAM%2Fcat-work.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fc.tenor.com%2FRlo-1wvJ_BgAAAAM%2Fcat-work.gif" alt="working-hard"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>performance</category>
      <category>java</category>
      <category>programming</category>
      <category>books</category>
    </item>
  </channel>
</rss>
