Errata

Java Performance: The Definitive Guide

Errata for Java Performance: The Definitive Guide

Submit your own errata for this product.

The errata list is a list of errors and their corrections that were found after the product was released. If the error was corrected in a later version or reprint the date of the correction will be displayed in the column titled "Date Corrected".

The following errata were submitted by our customers and approved as valid errors by the author or editor.

Color key: Serious technical mistake Minor technical mistake Language or formatting error Typo Question Note Update

Version Location Description Submitted By Date submitted Date corrected
PDF, ePub, Mobi
Page 9912
text

Typos:

"The are three" should be "There are three"

Current Copy
in terms of performance. XML validation is done against one more more schema or DTD files. Although validating against DTDs is

Suggested
"one more more schema" should be "one more schema"

Note from the Author or Editor:
Fixed in final edit.

Anonymous  Sep 18, 2019 
Printed
Page 380
calc() method using lambdas

Three variables a3, a2, a1 is defined as follows (same for all):
IntegerInterface a -> { return x };
Where this results in compilation error.
The correct way of defining the variables is this:
IntegerInterface a = () -> { return 3 };
or
IntegerInterface a = () -> 3;

Note from the Author or Editor:
This is corrected in the 2nd edition.

Ludvig Westerdahl  Aug 18, 2019 
Printed
Page 409
Colophon, 2nd paragraph

The colophon states that saiga can run at 80 mph. The correct value is 80 kilometers per hour, not miles per hour. This is roughly 48 miles per hour, still fast, but less so.

Note from the Author or Editor:
Please change mph to kph.

William Tyler  Jan 29, 2018 
Printed
Page 308
readObject method, TripHistory source code.

Missing end round bracket when creating new instance of Point class inside 'for' loop, on readObject method (TripHistory class):

airportsVisited[i] = new Point(ois.readInt(), ois.readInt();

should be:

airportsVisited[i] = new Point(ois.readInt(), ois.readInt());

Àngel Ollé Blázquez  Jun 05, 2017 
Printed
Page 265
DataHolder source code, in the middle of the page #265.

The class DataHolder defines the padding vars like:

pubilc long[] dummy1 = new long[128 / 8];

the word "pubilc" should be "public" in all occurrences.

Àngel Ollé Blázquez  Jun 05, 2017 
Printed
Page 78
Table 4-1

This is just a request for clarification.

Table 4-1 does not specify the units. I assume it is given in seconds.
Another this is, where is the time spent? Just the class-loading? How were they measured?

Note from the Author or Editor:
Please change the table title to read
Startup time (in seconds) of various applications

Anonymous  May 05, 2017 
Printed
Page 244
Last paragraph

Mentions

LinkedBlockedingQueue

should be

LinkedBlockingQueue

Stephen Souness  Oct 27, 2016 
Printed
Page 45
5th paragraph

The description of the data is backwards; it should read

In this output, there are 225.7 Kbps of data being read and 176.2 Kbps of data being written over the interface.

Scott Oaks
 
Sep 08, 2016 
PDF
Page 291
2nd paragraph

In chapter 10, under XML and JSON Processing, in the Overview of Parsing and Marshalling, the author mixes up the definitions of marshalling and unmarshalling:

Given a series of XML or JSON strings, a program must convert those strings into data suitable for processing by Java. This is called either marshalling or parsing, depending on the context and the resulting output. The reverse—producing XML or JSON strings
from other data—is called unmarshalling

As far as I know, converting a java object to XML/JSON is the marshalling, the reverse being unmarshalling (I know the names sound a little counterintuitive, but there it is)

Note from the Author or Editor:
Please change the first paragraph of "An Overview of Parsing and Marshalling" to read:

Given a series of XML or JSON strings, a program must convert those strings into data suitable for processing by Java. This is called either unmarshalling or parsing, depending on the context and the resulting output. The reverse -- producing XML or JSON strings from other data -- is called marshalling.

Tayo Koleoso  May 20, 2016 
Printed, PDF, ePub,
Page 68
Enabling JFR via the command line

The Flight recording options flag is given as -XX:+FlightRecorderOptions=string. However, there is no plus (+) sign for flight recorder options. It should be

-XX:FlightRecorderOptions=string

Note from the Author or Editor:
Please change occurrences of -XX:+FlightRecorderOptions=string to -XX:FlightRecorderOptions=string.

Vinayak Jallapelli  Apr 13, 2016 
Printed
Page 12
line 2,8,12

From page 12, page 13 and page 15, in the code and in the paragraphs, the author sometimes use fibImpl to indicate the method name, sometimes use fibImpl1 to indicate the method name. I believe only one method name should be used, and it probably is fibImpl.

Note from the Author or Editor:
On page 13, please change the text 'fibImpl(1000)' to fibImpl1(1000)'.

Yun Wu  Jan 06, 2016 
Printed
Page 143
3rd parapgrph

In the 3rd paragraph, there are words to calculate the old gen heap size after CMC old collector:

"In the collection at 98.049 seconds, the old generation occupies about 504MB".

The 504MB is the whole heap size, and as to the old gen, the value should be 435MB (504MB - 69MB).

Note from the Author or Editor:
Please change this sentence:

"In the collection at 98.049 seconds, the old generation occupies about 504 MB; the CMS cycle therefore cleaned up about 199 MB of memory."

to

"After the collection at 98.049 seconds, the entire heap occupies about 504 MB; the old generations occupies about 435 MB; and the CMS cycle therefore cleaned up about 268 MB of memory."

xliu  Jan 06, 2016 
PDF
Page 87
2nd paragraph, last sentence

(either directly of via the NIO libraries) ...

should be

(either directly or via the NIO libraries) ...

Anonymous  Dec 19, 2015 
PDF
Page 8
last sentence

"I assume you’ve done that analysis and determined that it is the Java component of your environment than needs to be improved."

should be

"I assume you’ve done that analysis and determined that it is the Java component of your environment that needs to be improved."

Notice "than" should be "that"

John Amos  Jan 12, 2015 
Printed
Page 246
ForkJoin Pool section


In chapter 9 there is a section titled "The ForkJoinPool" and the example given is described as the quicksort sorting algorithm. The algorithm used is in fact mergesort and not quicksort.

Note from the Author or Editor:
In the third paragraph of page 246, change to
"A classic example of this is the mergesort algorithm."

In the caption for Figure 9-1, change to
"Tasks in a recursive mergesort."

In the first paragraph of page 247, remove the sentence
"Current versions of Java use insertion sort when the array size is less than 47 elements."

In the first paragraph of page 248, remove the words
"quicksort and"

Isuru De Thabrew  Dec 24, 2014 
PDF
Page 155
Last paragraph

... reclaimed from the old generation
should be
... reclaimed from the young generation

Note from the Author or Editor:
The wording is correct as is, but it might be a little clearer if the first sentence of the final paragraph on page 155 were changed to these two sentences:

G1 has completed a marking cycle and has started performing mixed GCs to clean up the old regions. Before it can clean enough space, too many objects are promoted from the young generation, and so the old generation still runs out of space.

Anonymous  Oct 20, 2014  Dec 19, 2014
ePub
Page 999
United States

In Working with the "JIT Compiler"
"know as Java bytecodes" should be "known as Java bytecodes"

Note from the Author or Editor:
Appears in the final paragraph on page 74 of the printed edition.

Matt Doar  Oct 07, 2014  Dec 19, 2014
PDF
Page 31
2nd paragraph from the bottom

0.5 should be 0.05 and smaller should be larger.

Note from the Author or Editor:
The final two sentences of the last complete paragraph on page 31 should read:

Other commonly used a-values are 0.05 (95%) or 0.01 (99%). A test is considered statistically significant if the p-value is smaller than 1 - a-value.

[Maintain italics and alpha characters]

Anonymous  Sep 06, 2014  Dec 19, 2014
PDF
Page 30
Last line

... test is false.

should be

... test is true.

Note from the Author or Editor:
As described

Anonymous  Sep 05, 2014  Dec 19, 2014
Printed
Page 385
Table 12-11

Implemementation should be Implementation

Note from the Author or Editor:
Implemementation should be Implementation

Otmar Ertl  Jul 29, 2014  Dec 19, 2014
Printed
Page 384
code example (countSymbols)

The code example

public int countSymbols(ArrayList<String> al) {
int count = 0;
t = al.stream().
filter(symbol -> symbol.charAt(0) != 'A' &&
symbol.charAt(1) != 'A' &&
symbol.charAt(2) != 'A' &&
symbol.charAt(3) != 'A').
forEach(symbol -> count++);
return count;
}

has some flaws:
1) The return type of forEach is void, hence the assignment to "t" (which is neither declared nor used) is invalid.
2) The "count" variable cannot be modified within the lambda expression, because it is effectively final.

The stream class provides a count() method which can be used instead:

public int countSymbols(ArrayList<String> al) {
return (int) al
.stream()
.filter(
symbol -> symbol.charAt(0) != 'A' &&
symbol.charAt(1) != 'A' &&
symbol.charAt(2) != 'A' &&
symbol.charAt(3) != 'A')
.count();
}

Note from the Author or Editor:
The first implementation of the countSymbols method should be replaced with this:

private static long countFilter(ArrayList<String> al) {
long then = System.currentTimeMillis();
Stream<String> stream = al.stream();
stream.filter(
symbol -> symbol.charAt(0) != 'A' &&
symbol.charAt(1) != 'A' &&
symbol.charAt(2) != 'A' &&
symbol.charAt(3) != 'A').
forEach(symbol -> { count++; });
long now = System.currentTimeMillis();
return now - then;
}

The second example (immediately following) should be replaced with this:
private static long countIterator(ArrayList<String> al) {
long then = System.currentTimeMillis();
for (String symbol : al) {
if (symbol.charAt(0) != 'A' &&
symbol.charAt(1) != 'A' &&
symbol.charAt(2) != 'A' &&
symbol.charAt(3) != 'A')
count++;
}
return System.currentTimeMillis() - then;
}

Otmar Ertl  Jul 29, 2014  Dec 19, 2014
Printed
Page 197
code example

The values in the WeakHashMap should be weakly referenced . Hence, WeakHashMap<ImmutableObject, WeakReference<ImmutableObject>> should be used instead of WeakHashMap<ImmutableObject, ImmutableObject>.

See also the documentation of WeakHashMap (http://docs.oracle.com/javase/8/docs/api/java/util/WeakHashMap.html):

"Implementation note: The value objects in a WeakHashMap are held by ordinary strong references. Thus care should be taken to ensure that value objects do not strongly refer to their own keys, either directly or indirectly, since that will prevent the keys from being discarded. Note that a value object may refer indirectly to its key via the WeakHashMap itself; that is, a value object may strongly refer to some other key object whose associated value object, in turn, strongly refers to the key of the first value object. If the values in the map do not rely on the map holding strong references to them, one way to deal with this is to wrap values themselves within WeakReferences before inserting, as in: m.put(key, new WeakReference(value)), and then unwrapping upon each get."

For example,

WeakHashMap<Object, Object> map = new WeakHashMap<>();
while(true) {
Object o = new byte[1000000];
map.put(o,o);
}

runs immediately out of memory while

WeakHashMap<Object, WeakReference<Object>> map = new WeakHashMap<>();
while(true) {
Object o = new byte[1000000];
map.put(o,new WeakReference(o));
}

does not, because it allows for continuous garbage collection.

Note from the Author or Editor:
Change the code line reading

map.put(io, io);

to

map.put(io, new WeakReference(io));

Otmar Ertl  Jul 16, 2014  Dec 19, 2014
Printed
Page 197
code example

The WeakHahMap defined in ImmutableObject should be a static field instead of an instance field. In other words, there should be one map that all the instances use instead of a map per immutable object.

Note from the Author or Editor:
Change the line reading:

WeakHashMap<ImmutableObject, ImmutableObject> map = new WeakHashMap();

to

private static WeakHashMap<ImmutableObject, ImmutableObject> map = new WeakHashMap();

Chris Grindstaff  Jun 21, 2014  Dec 19, 2014
Other Digital Version
Basic VM Information
Basic VM Information

The string "other_options" is not part of the command

% java other_options -XX:+PrintFlagsFinal -version

If we run the command using "other_options" we will get:

Error: Could not find or load main class other_options

But if we run the command without this string:

% java -XX:+PrintFlagsFinal -version

then it works.

Clearly "other_options" it is meta information related to some possible options. It is not clear what other options we can use, though.

Thank you,

-Rod Oliveira

Note from the Author or Editor:
On page 48 of the printed version, in the command
% java other_options -XX:+PrintFlagsFinal -version
please set other_options in constant width italic

Change the first sentence of the next paragraph to read
You should include any other JVM options you intend to use on the command line because setting some options (particularly when setting GC-related flags) will affect the final value of other options.

Rod Oliveira  May 27, 2014  Dec 19, 2014
Printed,
Page 383
4th Paragraph

The text contains this wording:
"it tests to see if the second character is A"
but as the example shows, it should be
"it tests to see if the second character is not A"

Scott Oaks
 
May 23, 2014  Dec 19, 2014
Printed
Page 364
1st sentence

"f you are interesting in...

Should be

If you are interested in...

Rick Orr  May 21, 2014  Dec 19, 2014
PDF
Page xi
4th paragraph

says 'Paralellizing', should be Parallellizing

Note from the Author or Editor:
Actually, should be
parallelizing

Roger Schildmeijer  May 18, 2014  Dec 19, 2014