Since I got a lot of feedback for my my previous post where I built a very simple Ascii art generator in Java (find it on GitHub), I decided to continue with the project and add some more features to it you will hopefully enjoy even more. I’ve redesigned the major part of it and made it very extensible so it is very easy to use to test different algorithms, create different outputs, etc. In this post, I will present the new architecture of the project, so you can easily integrate it into your own code and extend it as needed.
At the company I work for, we had a situation where a highly loaded server that was handling several thousands requests per second consumed memory increasingly, and after about 30 days, it would become unusable and required a restart. By looking at our monitoring tools, we concluded it was clearly a memory leak, and we figured it must be an easy one to detect as memory exhibited an almost perfect linear grow. First thing we did was we took a heap dump and looked at most frequent instances and to our shock over 30 GB of memory was occupied by log4j loggers!
Ascii art is a technique that uses printable characters from ASCII standard to produce visual art. It had it’s purpose in history when printers lacked graphics ability and it was also used in emails when embedding images was yet not possible. I present you a very simple ascii art generator written in Java with configurable font and contrast. Since it was built over a few hours during the weekend, it is not optimal but it was a fun experiment. Down below you can see the code in action and an explanation of how it works.
Deadlocks are situations in which two or more actions are waiting for the others to finish, making all actions in a blocked state forever. They can be very hard to detect during development, and they usually require restart of the application in order to recover. To make things worse, deadlocks usually manifest in production under the heaviest load, and are very hard to spot during testing. The reason for this is it’s not practical to test all possible interleavings of a program’s threads. Although some statical analysis libraries exist that can help us detect the possible deadlocks, it is still necessary to be able to detect them during runtime and get some information which can help us fix the issue or alert us so we can restart our application or whatever.
Since Java SE 5.0, developing multithreaded applications became much easier due to the task executor framework. Instead of working with low level synchronization constructs, the framework introduces the concepts of Task and Executors. It also provides isolation between task submission and task execution, allowing to easily change execution policy without even touching submission logic. Still, it doesn’t save you from creating race conditions and other difficult to debug and discover bugs, so in order to use the framework to its full power, I recommend starting from basics. A great book that covers almost everything you need to know about multithreading in Java is Java Concurrency in Practice by Brian Goetz and its a must if you are developing in Java. In this article, I will show you how to create a useful utility class for managing a pool of expensive objects, and how simple it is to create complex structures by reusing what Java offers.
Even with hardware becoming more powerful everyday, it is essential to keep the response time small for complex applications which use large amounts of data. Many database performance problems can be addressed by analyzing and optimizing SQL queries, which many developers avoid to learn or do. Part of the problem is that there is no magic bullet that we can read and follow - a query that runs locally just fine can fail miserably on production system. The problems that you solve may or may not manifest on a similar system, and vice versa. When I first started with PostreSQL, analyzing queries looked like black magic but once you get the basics it becomes a fun process.
In my previous post, we explored ways how we can optimize batch inserts with Hibernate and keeping our heap memory consumption at a reasonable level. If you played with that code yourself and looked at SQL it generates, you would notice two things:
In this article, we are going to see how we can change that and measure how much can we gain. If your application is doing lots of inserts, you can optimize sequence allocation by using HiLo algorithm.
In case you missed the previous article, I really recommend to read it. The series are best followed when read in order and each will contain one common problem with proposed solutions, measured evidence and pros/cons of the solutions. I talked about one possible performance trap using hibernate and that was how to update a large number of objects in a loop which can cause severe performance drops and large memory overhead if done wrong. In this post, we will tackle a similar requirement - how to achieve best performance when inserting a large number of records.
Hibernate is the most popular Object-Relational Mapping (ORM) library for Java. It provides a framework for mapping object-oriented domain models to the underlying relational database and also generates SQL for retrieving and persisting the data. This convenience allows developers to focus on business logic without having to worry too much about data access details, allowing more rapid development. However, this often comes with a hidden price, as it is easy to write suboptimal code with problems that usually manifest in production with larger scale of data and when it’s very costly to fix them. In the next series of posts, I will share with you some of the most common performance traps or anti-patterns in Hibernate that are easy to fix and can provide huge instant performance gains. Keep in mind that those features don’t indicate faults in Hibernate, but incorrect usage of the tool and in some cases limitations of the ORM frameworks in general.
Subscribe via RSS.