hotspot and stuff

43 views
Skip to first unread message

Kirk Pepperdine

unread,
Mar 1, 2012, 6:01:46 AM3/1/12
to java...@googlegroups.com
Hey all,

Just a few comments on the inline keyword and it's effectiveness. I would fear that having a develop who many have little understanding of hotspot would abuse such a keyword. I would fear that this abuse would cause the resulting code produced by javac to surpass limits that can prevent the bytecode from being jit'ed. In most cases, as Dick pointed out, the keyword isn't needed because hotspot will aggressively inline trivial methods. The larger the method, the more likely that it won't be inlined and the more likely that it may not be jit'ed. The limit on compilation is dictated by the number of ideal nodes needed by Hotspot's high level intermediate representation (SSA, CFG combined with call counts for clients and Sea of Nodes (a variant of SSA) combined with CFG, call counts and a VDG for server). Other constraints include method size (35 byte codes), depth of nesting (9). Having the compiler synthetically create large methods goes against the coding style of use small methods that drives Hotspot's optimizations. Charlie Nutter spends a lot of his time making sure that JRuby produced bytecodde that will not break the optimizers in HotSpot.

On the question of System.gc(). The spec states that the VM may ignore the call. In fact, the VMs don't ignore the calls. The calls are synchronized and will run one after the other. Since back to back GC calls don't do much they don't tend to last very long. Even so, they are very disruptive to overall application throughput as you end up parking mutators @ safe points, winding up GC threads only to have them wind down and then releasing mutators that all need to be rescheduled. And all of this for little or no gain. For this reason we have been battling the RMI guys to quit making calls to System.gc(). The response has been to back off the frequency of calls from once a minute to once every 5 minutes and now it's down to once every 30 minutes. From their point of view, they need the call to run when they call it so having the JVM say, nope, not going to do it, wouldn't work.

On the question of finalization I'm going to say that finalization does exactly what it was intended to do and for those purposes it works very well. The newer JVM will parallelize the process in that it will use more than 1 helper thread. So, the problem isn't really with finalization, it's just gotten a bad name when people were looking for free(). On this point, I will happily defend Mark Reinhold's work. it's not that bad, just don't abuse it. But doesn't that go for just about everything else?

On the question of Strings, StringBuffer/Builder and copying char arrays. Sorry to say that this is still a huge performance drain in many applications. It's the only place where I miss c pointers ;-). Hotspot rarely does the right thing when it comes to string and string manipulation. It's javac that makes the biggest impact (string1 + string2 is converted to using StringBuilder and so on). So here are a few rules when working with strings.

Rule #1, don't copy them or force them to copy themselves.
Rule #2, use a flyweight instead of a copy
Rule #3, don't copy them or force them to copy themselves.
Rule #4, use System.arraycopy, it is the most efficient way to copy a primitive array.

Regards,
Kirk

Fabrizio Giudici

unread,
Mar 1, 2012, 6:08:36 AM3/1/12
to java...@googlegroups.com, Kirk Pepperdine
On Thu, 01 Mar 2012 12:01:46 +0100, Kirk Pepperdine
<kirk.pe...@gmail.com> wrote:


> On the question of Strings, StringBuffer/Builder and copying char
> arrays. Sorry to say that this is still a huge performance drain in many
> applications. It's the only place where I miss c pointers ;-). Hotspot
> rarely does the right thing when it comes to string and string
> manipulation. It's javac that makes the biggest impact (string1 +
> string2 is converted to using StringBuilder and so on). So here are a
> few rules when working with strings.
>
> Rule #1, don't copy them or force them to copy themselves.
> Rule #2, use a flyweight instead of a copy
> Rule #3, don't copy them or force them to copy themselves.
> Rule #4, use System.arraycopy, it is the most efficient way to copy a
> primitive array.

Perhaps does this explain why e.g. Perl is still faster than Java in some
heavy text manipulation benchmarks? (not my direct experience, I'm not
using Perl since a lot of time, this assertion just came up a few weeks
ago in a JUG discussion out of a reputable commenter).


--
Fabrizio Giudici - Java Architect, Project Manager
Tidalwave s.a.s. - "We make Java work. Everywhere."
fabrizio...@tidalwave.it
http://tidalwave.it - http://fabriziogiudici.it

Kirk Pepperdine

unread,
Mar 1, 2012, 6:14:51 AM3/1/12
to java...@googlegroups.com

On 2012-03-01, at 12:08 PM, Fabrizio Giudici wrote:

> On Thu, 01 Mar 2012 12:01:46 +0100, Kirk Pepperdine <kirk.pe...@gmail.com> wrote:
>
>
>> On the question of Strings, StringBuffer/Builder and copying char arrays. Sorry to say that this is still a huge performance drain in many applications. It's the only place where I miss c pointers ;-). Hotspot rarely does the right thing when it comes to string and string manipulation. It's javac that makes the biggest impact (string1 + string2 is converted to using StringBuilder and so on). So here are a few rules when working with strings.
>>
>> Rule #1, don't copy them or force them to copy themselves.
>> Rule #2, use a flyweight instead of a copy
>> Rule #3, don't copy them or force them to copy themselves.
>> Rule #4, use System.arraycopy, it is the most efficient way to copy a primitive array.
>
> Perhaps does this explain why e.g. Perl is still faster than Java in some heavy text manipulation benchmarks? (not my direct experience, I'm not using Perl since a lot of time, this assertion just came up a few weeks ago in a JUG discussion out of a reputable commenter).

I'm not sure how Perl treats strings but if it runs though it a char at a time without copying... perfect.... it will beat the cr@p out of Java. Not only a Java problem, I think Dick mentioned Smalltalk. Smalltalk was also horrible with Strings. It's only saving grace was that String wasn't a final class which meant you could extend it in some very useful ways that mitigated the copy costs. Having String declared final by some developer in Santa Clara wanting to be my mother is one of my top pet peeves... ;-)

Regards,
Kirk

Kevin Wright

unread,
Mar 1, 2012, 6:20:26 AM3/1/12
to java...@googlegroups.com
I never really had a big problem with String being final, although the claims that it was for security reasons seem a bit weak given that strings are also immutable.

On the other hand, making enums and the URL type final after giving them both such a hideously broken hashCode implementation... That definitely numbers amongst the top 10 questionable design decisions in Java.

Ricky Clarkson

unread,
Mar 1, 2012, 6:26:01 AM3/1/12
to java...@googlegroups.com
The questionable decision there wasn't making them final, but giving them a broken hashCode implementation.
--
Skype: ricky_clarkson


--
You received this message because you are subscribed to the Google Groups "The Java Posse" group.
To post to this group, send email to java...@googlegroups.com.
To unsubscribe from this group, send email to javaposse+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/javaposse?hl=en.

Kirk Pepperdine

unread,
Mar 1, 2012, 6:36:27 AM3/1/12
to java...@googlegroups.com

The questionable decision there wasn't making them final, but giving them a broken hashCode implementation.

I often wish I could extend String to provide a more useful String that all of my code could use. In fact, I wonder if String shouldn't have been an interface so I could have ASCIIString, UTF8String, and so on. Might even be able to get rid of utility classes like StringBuilder and StringBuffer...

Kirk

Kevin Wright

unread,
Mar 1, 2012, 6:37:16 AM3/1/12
to java...@googlegroups.com
That's true enough.

For an example where the only problem is an inappropriate use of final, I reckon that Spring's MVC framework takes the record for making me tear out the most hair.  Doesn't really count as a language-level issue though.

Kevin Wright

unread,
Mar 1, 2012, 6:39:52 AM3/1/12
to java...@googlegroups.com
I guess that interface would have to be CharSequence.  But it isn't as useful as it could be because so many methods only accept and return Strings, instead of CharSequences.

Reinier Zwitserloot

unread,
Mar 1, 2012, 9:37:54 AM3/1/12
to java...@googlegroups.com
On Thursday, March 1, 2012 12:20:26 PM UTC+1, KWright wrote:
I never really had a big problem with String being final, although the claims that it was for security reasons seem a bit weak given that strings are also immutable.


If String wasn't final, it would obviously not be immutable, duh.

Kirk Pepperdine

unread,
Mar 1, 2012, 9:46:19 AM3/1/12
to java...@googlegroups.com
I can protect the underlying char[] without making the class final. Making the class final kills all chance of extending which denies developers of the tools that OO brings to the table.

Regards,
Kirk

Fabrizio Giudici

unread,
Mar 1, 2012, 10:03:08 AM3/1/12
to java...@googlegroups.com, Kirk Pepperdine
On Thu, 01 Mar 2012 15:46:19 +0100, Kirk Pepperdine
<kirk.pe...@gmail.com> wrote:


> I can protect the underlying char[] without making the class final.
> Making the class final kills all chance of extending which denies
> developers of the tools that OO brings to the table.

It's a tough question. I personally appreciate final a lot, but it depends
on the context. For instance, for a typical, self-contained open source
project that can evolve quickly I'd be positive on final: you just seal
everything that you don't expect to be extended. If somebody asks for a
reasonable extension it's easy to remove a final in a next release. But
for the JDK which is elephantiac, can't be modified and released too often
I understand final can be a problem. Nevertheless, for String not having
final could have opened a can of worms for security.

Carl Jokl

unread,
Mar 1, 2012, 10:04:51 AM3/1/12
to The Java Posse
I think it may cause complications protecting the internal character
array if String is not final. I suppose the character array could be
declared private and final. If not then any subclass would be able to
modify the internal character array. Without access to the internal
character array then the functionality is limited to that exposed
through the Strings public or protected methods. In that case
extension functionality may be little different from aggregating a
String inside another object or by having external String processing
methods on another object. It might not be as neat but using things
like static String processor methods and some static imports it could
be treated like passing a String to a function. Messing around with
things like equality and hash codes could break equality behaviour
guarantees and cause problems in all the places where Strings are used
as keys or values in collections. Having optimised code for processing
Strings in place would require a whole different String implementation
that is mutable. As regards a String interface, Java already has a
CharSequence interface that tries to in some way achieve this. Perhaps
some kind of MutableString class could be introduced that is not a
subclass of String but rather is an implementation of CharSequence
that makes changes in place. This would allow new code to use the
mutable String without accidentally passing it to any existing code
that relies on String being immutable. A CharSequence can be converted
into a regular immutable String anyway after all. If the code is that
performance and memory sensitive then perhaps more of the API's could
be modified to work with CharSequence implementations rather than
String. It is still possible to write your own CharSequence
implementation that is mutable today if you wanted to.

Kirk Pepperdine

unread,
Mar 1, 2012, 10:08:59 AM3/1/12
to java...@googlegroups.com
right, but name an (useful) API that relies on CharSequence...

Kirk

Carl Jokl

unread,
Mar 1, 2012, 10:17:45 AM3/1/12
to The Java Posse
Doesn't the StringBuilder use it?

Given that CharSequence was added later in the life of Java, maybe the
original intension was that it would be used for more things and to be
honest it could be. It would be safe to refractor existing APIs to
take a CharSequence wherever the immutable String behaviour does not
matter. It should always be possible to make a method parameter less
specific as long as the parameter is still compatible due to
polymorphism. It could be done, not to say that it would. It might
create problems for things like reflection if existing code is invoked
via reflection and is hard coded to expect a parameter type of String
but reflection can cause tricky situations anyway.

It might push some more responsibility on to calling code when passing
a CharSequence into a method that is not thread safe.

Carl

Kirk Pepperdine

unread,
Mar 1, 2012, 10:23:53 AM3/1/12
to java...@googlegroups.com

On 2012-03-01, at 4:17 PM, Carl Jokl wrote:

> Doesn't the StringBuilder use it?

part of the same problem.. Pattern.matcher() uses it.


>
> It might push some more responsibility on to calling code when passing
> a CharSequence into a method that is not thread safe.

hummm, encapsulation is broken


Kirk

Carl Jokl

unread,
Mar 1, 2012, 10:27:58 AM3/1/12
to The Java Posse
In that case then it may be better to live with the immutability and
the performance and memory impact of that.

Fabrizio Giudici

unread,
Mar 1, 2012, 10:45:53 AM3/1/12
to java...@googlegroups.com, Kirk Pepperdine
On Thu, 01 Mar 2012 16:08:59 +0100, Kirk Pepperdine
<kirk.pe...@gmail.com> wrote:

> right, but name an (useful) API that relies on CharSequence...

Right, but this is probably a fault of us developers. Perhaps Sun didn't
advertise enough the use of CharSequence.

Kirk Pepperdine

unread,
Mar 1, 2012, 10:49:15 AM3/1/12
to java...@googlegroups.com
sorry, I take that back. I don't want String or CharSequence to assume any threading model. It is up to the responsibility of the client of the class to know how it's being used and to treat it accordingly. There are a number of classes in the JDK that are broken because they over-reached.

Regards,
Kirk

Kevin Wright

unread,
Mar 1, 2012, 12:05:14 PM3/1/12
to java...@googlegroups.com
Not so, a thing can be both extensible and immutable.  All that's necessary is for the *members* of an immutable object to be final and for methods to be pure, you can then happily subclass and add functionality to your heart's extent.

Some hypothetical SubclassedString won't necessarily be immutable, but it shouldn't be able to mutate in a way that's visible to any method using it typed as a String (otherwise you have an LSP violation).  In the case of a String, it's enough that the backing char[] and a few methods are marked final.

There's still value in subclassing an immutable object, such as access to protected fields, or the ability to override a broken hashCode implementation.

Ricky Clarkson

unread,
Mar 1, 2012, 3:49:55 PM3/1/12
to java...@googlegroups.com

I'd rather take a String anyway because it guarantees things that CharSequence doesn't.

I guess wanting to subclass to add methods just shows how useful extension methods will be.

Doing it to make String mutable would stink.

--
Reply all
Reply to author
Forward
0 new messages