StringBuffer, and how hard it is to get rid of the legacy of old code
Hello. This article is a free translation of the post by StringBuffer, and how hard it is to get rid of legacy code . Somehow he really sunk into my soul, so he decided to translate. Go.
In 2006, in the 5th java appeared
Having
So that? It turns out that 10 years later no one uses StringBuffer !? Well, at least, definitely not for the new functionality !?
As I wrote earlier, the virtual machine creates many objects at startup or when loading the main libraries. Much more than you could imagine by asking the question above:
Version 8 Oracle JVM creates approximately 10_000 objects to run this program.
So, to start the JVM you need to create a lot of objects, but old classes that have a faster alternative that shouldn't be used for 10 years, right?
While the process is running, we can execute the following command:
and get:
129 is the number of objects
(I checked 131 on my Java 8 update 131, received only 14 objects).
What about new features - lambdas and streams? They were created explicitly in the last 10 years and use some third-party libraries, such as Objectwebs ASM. And these developers know exactly the inside of the virtual machine and had to design new features as light as possible.
We start
Additional 416 objects for the simplest lambda and stream!
(Again I checked 131 on my Java 8 update 131 and received 430 objects, that is, the difference in the same 416 objects. It seems that the streams and lambdas have not been erased).
By the way, the program above generally creates:
or 35_486 objects!
Of course, using StringBuffer at the start of the application does not make much difference, but knowing that there is a suitable alternative and StringBuffer is still used even in new features - it shows how difficult it is to get rid of the legacy of old code or change people's minds to use best practices.
PS
In the original post, they left a link to the ticket from
So it’s quite possible in 3 months we will be left without a heritage :), though it's only about
In 2006, in the 5th java appeared
StringBuilder. A lighter and more reasonable alternative StringBuffer. Here is what says the official documentation on StringBuffer:This class is supplemented by a similar class intended for use in a single thread - StringBuilder. In general, you should give preference to the StringBuilder class, since it supports all the same operations as this (StringBuffer), but faster, since it does not perform any synchronization.
Having
synchronizedin StringBuffergeneral has never been a good idea. The main problem is that one operation is never enough. Single concatenation is .append(x)useless without other operations, such as .append(y)and .toString(). At a time when each particular method is thread safe, you cannot make multiple calls without competition between threads. Your only option is external synchronization. So that? It turns out that 10 years later no one uses StringBuffer !? Well, at least, definitely not for the new functionality !?
How many objects does this code create?
As I wrote earlier, the virtual machine creates many objects at startup or when loading the main libraries. Much more than you could imagine by asking the question above:
public class Main {
public static void main(String... args) {
System.out.println("Hello " + "world");
}
}
Version 8 Oracle JVM creates approximately 10_000 objects to run this program.
How much is StringBuffers creating?
So, to start the JVM you need to create a lot of objects, but old classes that have a faster alternative that shouldn't be used for 10 years, right?
public class Main {
public static void main(String[] args) throws IOException {
System.out.println("Waiting");
System.in.read();
}
}While the process is running, we can execute the following command:
jmap -histo {pid} | grep StringBufferand get:
18: 129 3096 java.lang.StringBuffer129 is the number of objects
StringBufferJava 8 Update 121 created. This is less than the last time I checked, but still, a little surprisingly. (I checked 131 on my Java 8 update 131, received only 14 objects).
What about new features - lambdas and streams? They were created explicitly in the last 10 years and use some third-party libraries, such as Objectwebs ASM. And these developers know exactly the inside of the virtual machine and had to design new features as light as possible.
public class Main {
public static void main(String[] args) throws IOException {
IntStream.range(0, 4).forEach(System.out::println);
System.out.println("Waiting");
System.in.read();
}
}We start
jmapagain and what do we see? 17: 545 13080 java.lang.StringBufferAdditional 416 objects for the simplest lambda and stream!
(Again I checked 131 on my Java 8 update 131 and received 430 objects, that is, the difference in the same 416 objects. It seems that the streams and lambdas have not been erased).
By the way, the program above generally creates:
Total 35486 4027224or 35_486 objects!
conclusions
Of course, using StringBuffer at the start of the application does not make much difference, but knowing that there is a suitable alternative and StringBuffer is still used even in new features - it shows how difficult it is to get rid of the legacy of old code or change people's minds to use best practices.
PS
In the original post, they left a link to the ticket from
StringBuffer9. So it’s quite possible in 3 months we will be left without a heritage :), though it's only about
StringBuffer. Do not forget about Vector, Hashtableand other amenities.