|
The Java Specialists' Newsletter
Issue 059b 2002-11-13
Category:
Performance
Java version: Follow-up to Loooong Stringsby Dr. Heinz M. Kabutz
Thanks to those of you who wrote back after my last newsletter.
There are some issues I want to follow-up on.
To start off, the date on the newsletter was incorrect.
Then, the original topic of this newsletter was "Verrrrrry looooong Strings
and other things". One of my subscribers from Poland suggested
that the topic did not really represent the content as there is no
real limit on how long ordinary Strings can be, except for the limit on
char array length and physical memory. I renamed it to:
"When arguments get out of hand..."
Talking about long constant Strings, many thanks to
Frank Peters from Process Management Consulting in Cologne for
pointing out the problem with long constant Strings to me at the
beginning of June 2002. Apologies for forgetting to thank you in
the original newsletter, our email conversation had slipped my
conscious mind. Something that Frank pointed out to me
in the original discussion was that if you have a unicode
character, it might be converted to more than two bytes in certain
circumstances, so the limit is actually less than 65535 in some
cases.
Some readers also wrote to tell me that the problem with looong
constant Strings used to appear with JSP pages generated by
Dreamweaver.
Last, but definitely not least, thanks to Bjorn Carlin for
sending me the secret to the 14 missing data members. Thank you
also to John Bester from South Africa and Juan C. Valverde from
ArtInSoft in Costa Rica for sending me their ideas.
The missing 14 fields
The limit on the fields is actually the limit in the constant
pool where the names of the fields are stored. Bjorn told me
that the 9th and 10th bytes of the class file tell you how many
constant fields are in the class. He also sent me output from
a little program he wrote that dumped the constant pool from
a class.
Here is a piece of code that tells you the size of the constant
pool for a classfile:
import java.io.*;
public class ConstantPoolSize {
static void skip(InputStream in, int skip) throws IOException {
while(skip > 0) {
skip -= in.skip(skip);
}
}
public static void main(String[] args) throws IOException {
DataInputStream din = new DataInputStream(
new FileInputStream(args[0]));
skip(din, 8);
int count = ((din.readByte() & 0xff) << 8)
| (din.readByte() & 0xff);
System.out.println(count);
din.close();
}
}
I'll let you figure out the reason for skip() yourself ;-)
Run it against a small class such as:
public class Small {}
You will get different results depending with which debugging info
options you compiled Small.java. The default compile will tell you
that there are 13 entries in Small.class. If you add one field,
you will have 15 entries, one for the name of the field, and one
for the type of the field. For example, if you add an
int a0;, you will have entries "I" and "a0".
You can compile BigClass with the -g:none option, then you can
squeeze more fields in. In addition, if you call one field "I"
and another "Code", you can get two more fields into your class.
"I" is the type of int defined in the constants table. I don't
know where "Code" comes from, but it works.
The maximum number of fields I've therefore managed to squeeze in
like this was 65526.
Now that's really overrevving Java ;-)
Heinz
P.S. Probably the worst mistake in the newsletter was that I said
my rev counter was limited to 6000 revolutions per minute. That
of course is nonsense. It is limited to 7000 revs. I checked
today. When I wrote the newsletter, I did not feel like going to
the garage to look. Besides, at 1:00am that might have made my
neighbours unhappy ;-)
Performance Articles
Related Java Course
Discuss at The Java Specialist Club
|