Skip to content

Commit 37eadd6

Browse files
committed
Added two more sample to check hot methods and latencies in JFR
1 parent 73e4c6c commit 37eadd6

File tree

10 files changed

+359
-8
lines changed

10 files changed

+359
-8
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ target/
1515
.project
1616
.classpath
1717

18+
#Idea Files
19+
.idea
20+
*.iml
21+
1822
tmp/
1923
*.tmp
2024
*.bak

README.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,9 @@ Sample Java Programs
55

66
This repository contains some sample programs. All are Maven projects and can be run directly using "java -jar"
77

8+
## How to build
89

9-
## Java Programs
10-
11-
**highcpu**
12-
13-
A java program consuming high CPU usage. This program was inspired by a sample found in the article "[Identifying which Java Thread is consuming most CPU](http://code.nomad-labs.com/2010/11/18/identifying-which-java-thread-is-consuming-most-cpu/)"
10+
Run `mvn clean install` to build all sample programs
1411

1512
## License
1613

highcpu/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Sample program consuming high CPU usage
2+
=======================================
3+
4+
A java program consuming high CPU usage. This program was inspired by a sample found in the article "[Identifying which Java Thread is consuming most CPU](http://code.nomad-labs.com/2010/11/18/identifying-which-java-thread-is-consuming-most-cpu/)"
5+

hotmethods/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Sample to show hot methods in Java Flight Recording
2+
===================================================
3+
4+
This program checks whether a given random number is primitive or not.
5+
6+
Run the program without any arguments and also make a profiling recording.
7+
8+
For example:
9+
`java -XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:StartFlightRecording=settings=profile,duration=60s,name=Hotmethods,filename=hotmethods.jfr -XX:FlightRecorderOptions=loglevel=info -jar target/hotmethods.jar`
10+
11+
In Code -> Hot Methods tab, you should see that the program has spent a lot of time in the LinkedList.indexOf(Object) method, which is called from contains method.
12+
13+
By changing LinkedList to a HashSet, you can make the program run a lot faster.
14+
15+
The contains methods in Linked List checks all the items. Algorithm run time is O(n). However the HashSet contains algorithm's run time is O(1).
16+
17+
Check the runtime using HashSet.
18+
`java -XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:StartFlightRecording=settings=profile,duration=60s,name=Hotmethods,filename=hotmethods.jfr -XX:FlightRecorderOptions=loglevel=info -jar target/hotmethods.jar --use-set`
19+
20+
Use `time` command in Linux to measure the time.

hotmethods/pom.xml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
# Copyright 2017 M. Isuru Tharanga Chrishantha Perera
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
-->
17+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
18+
19+
<parent>
20+
<groupId>com.github.chrishantha.sample</groupId>
21+
<artifactId>java-samples</artifactId>
22+
<version>0.0.2-SNAPSHOT</version>
23+
<relativePath>../pom.xml</relativePath>
24+
</parent>
25+
26+
<modelVersion>4.0.0</modelVersion>
27+
<artifactId>hotmethods</artifactId>
28+
<packaging>jar</packaging>
29+
<name>hotmethods</name>
30+
31+
<dependencies>
32+
<dependency>
33+
<groupId>com.beust</groupId>
34+
<artifactId>jcommander</artifactId>
35+
</dependency>
36+
</dependencies>
37+
38+
39+
<properties>
40+
<fully.qualified.main.class>com.github.chrishantha.sample.hotmethods.App</fully.qualified.main.class>
41+
</properties>
42+
</project>
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* Copyright 2017 M. Isuru Tharanga Chrishantha Perera
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.github.chrishantha.sample.hotmethods;
17+
18+
import com.beust.jcommander.JCommander;
19+
import com.beust.jcommander.Parameter;
20+
21+
import java.util.Collection;
22+
import java.util.HashSet;
23+
import java.util.LinkedList;
24+
import java.util.Random;
25+
26+
public class App {
27+
28+
@Parameter(names = "--count", description = "Random Numbers Count")
29+
private int randomNumbersCount = 1000000;
30+
31+
@Parameter(names = "--max", description = "Maximum limit to generate prime numbers")
32+
private int max = 100000;
33+
34+
@Parameter(names = "--use-set", description = "Use Hash Set for Prime Numbers", arity = 0)
35+
private boolean useSet;
36+
37+
@Parameter(names = "--help", description = "Display Help", help = true)
38+
private boolean help;
39+
40+
public static void main(String[] args) {
41+
App app = new App();
42+
final JCommander jcmdr = new JCommander(app);
43+
jcmdr.setProgramName(App.class.getSimpleName());
44+
jcmdr.parse(args);
45+
46+
System.out.println(app);
47+
48+
if (app.help) {
49+
jcmdr.usage();
50+
return;
51+
}
52+
53+
app.start();
54+
}
55+
56+
private void start() {
57+
Collection<Integer> primeNumbers = useSet ? new HashSet<>() : new LinkedList<>();
58+
System.out.println("Generating Prime numbers between 1 and " + max);
59+
for (int i = 1; i < max; i++) {
60+
boolean isPrimeNumber = true;
61+
// Check whether the number is prime
62+
for (int j = 2; j < i; j++) {
63+
if (i % j == 0) {
64+
isPrimeNumber = false;
65+
break;
66+
}
67+
}
68+
69+
if (isPrimeNumber) {
70+
primeNumbers.add(i);
71+
}
72+
}
73+
74+
Random random = new Random();
75+
System.out.println("Checking Random Prime numbers");
76+
int count = 0;
77+
for (int i = 1; i < randomNumbersCount; i++) {
78+
int randomNumber = random.nextInt(max);
79+
if (primeNumbers.contains(randomNumber)) {
80+
count++;
81+
}
82+
}
83+
System.out.format("Found %d prime numbers from %d random numbers%n", count, randomNumbersCount);
84+
}
85+
86+
@Override
87+
public String toString() {
88+
StringBuilder builder = new StringBuilder();
89+
builder.append("App [randomNumbersCount=");
90+
builder.append(randomNumbersCount);
91+
builder.append(", max=");
92+
builder.append(max);
93+
builder.append(", useSet=");
94+
builder.append(useSet);
95+
builder.append("]");
96+
return builder.toString();
97+
}
98+
}

latencies/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Sample to show latencies in Java Flight Recording
2+
=================================================
3+
4+
This program has two threads: Even and Odd to print Even and Odd numbers.
5+
6+
Run the program without any arguments and also make a profiling recording.
7+
8+
For example:
9+
`java -jar -XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:StartFlightRecording=settings=profile,duration=30s,name=Latencies,filename=latencies.jfr -XX:FlightRecorderOptions=loglevel=info target/latencies.jar`
10+
11+
In Threads -> Latencies tab, you should see that the program has many blocked events.
12+
13+
You should also see red blocks in Events -> Graph tab. Red blocks are not good as the thread is just waiting to acquire a lock.
14+
15+
See Threads -> Contention tab to see the Locks and also see Threads -> Lock Instances to check whether both threads share the same lock instances.
16+
17+
Since there is no shared resource, you can avoid the lock and improve the performance.
18+
19+
Run the program without locks.
20+
`java -jar -XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:StartFlightRecording=settings=profile,duration=30s,name=Latencies,filename=latencies-fixed.jfr -XX:FlightRecorderOptions=loglevel=info target/latencies.jar --lock false`

latencies/pom.xml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
# Copyright 2017 M. Isuru Tharanga Chrishantha Perera
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
-->
17+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
18+
19+
<parent>
20+
<groupId>com.github.chrishantha.sample</groupId>
21+
<artifactId>java-samples</artifactId>
22+
<version>0.0.2-SNAPSHOT</version>
23+
<relativePath>../pom.xml</relativePath>
24+
</parent>
25+
26+
<modelVersion>4.0.0</modelVersion>
27+
<artifactId>latencies</artifactId>
28+
<packaging>jar</packaging>
29+
<name>latencies</name>
30+
31+
<dependencies>
32+
<dependency>
33+
<groupId>com.beust</groupId>
34+
<artifactId>jcommander</artifactId>
35+
</dependency>
36+
</dependencies>
37+
38+
39+
<properties>
40+
<fully.qualified.main.class>com.github.chrishantha.sample.latencies.App</fully.qualified.main.class>
41+
</properties>
42+
</project>
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/*
2+
* Copyright 2017 M. Isuru Tharanga Chrishantha Perera
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.github.chrishantha.sample.latencies;
17+
18+
import com.beust.jcommander.JCommander;
19+
import com.beust.jcommander.Parameter;
20+
21+
public class App {
22+
23+
@Parameter(names = "--count", description = "Print Count")
24+
private int count = 50;
25+
26+
@Parameter(names = "--lock", description = "Lock", arity = 1)
27+
private boolean lock = true;
28+
29+
@Parameter(names = "--help", description = "Display Help", help = true)
30+
private boolean help;
31+
32+
public static void main(String[] args) {
33+
App app = new App();
34+
final JCommander jcmdr = new JCommander(app);
35+
jcmdr.setProgramName(App.class.getSimpleName());
36+
jcmdr.parse(args);
37+
38+
System.out.println(app);
39+
40+
if (app.help) {
41+
jcmdr.usage();
42+
return;
43+
}
44+
45+
app.start();
46+
}
47+
48+
49+
private class EvenThread extends Thread {
50+
51+
public EvenThread() {
52+
super("Even-Thread");
53+
}
54+
55+
@Override
56+
public void run() {
57+
for (int i = 0; i < count; i++) {
58+
printEven(i);
59+
}
60+
}
61+
}
62+
63+
private class OddThread extends Thread {
64+
65+
public OddThread() {
66+
super("Odd-Thread");
67+
}
68+
69+
@Override
70+
public void run() {
71+
for (int i = 0; i < count; i++) {
72+
printOdd(i);
73+
}
74+
}
75+
}
76+
77+
78+
private void printNumber(int i) {
79+
System.out.format("Thread: %s, Number: %d%n", Thread.currentThread().getName(), i);
80+
}
81+
82+
private void printEven(int i) {
83+
if ((lock && isEvenLocked(i)) || isEven(i)) {
84+
printNumber(i);
85+
}
86+
}
87+
88+
private void printOdd(int i) {
89+
if ((lock && !isEvenLocked(i)) || !isEven(i)) {
90+
printNumber(i);
91+
}
92+
}
93+
94+
private synchronized boolean isEvenLocked(int i) {
95+
return isEven(i);
96+
}
97+
98+
private boolean isEven(int i) {
99+
try {
100+
Thread.sleep(1000);
101+
} catch (InterruptedException e) {
102+
e.printStackTrace();
103+
}
104+
return i % 2 == 0;
105+
}
106+
107+
private void start() {
108+
new OddThread().start();
109+
new EvenThread().start();
110+
}
111+
112+
@Override
113+
public String toString() {
114+
StringBuilder builder = new StringBuilder();
115+
builder.append("App [count=");
116+
builder.append(count);
117+
builder.append("]");
118+
return builder.toString();
119+
}
120+
}

0 commit comments

Comments
 (0)