Posts

Storing 1 TB in Virtual Memory on a 64 GB Machine with Chronicle Queue

Image
As Java developers, we often face the challenge of handling very large datasets within the constraints of the Java Virtual Machine (JVM). When the heap size grows significantly—often beyond 32 GB—garbage collection (GC) pause times can escalate, leading to performance degradation. This article explores how Chronicle Queue enables the storage and efficient access of a 1 TB dataset on a machine with only 64 GB of RAM. The Challenge of Large Heap Sizes Using standard JVMs like Oracle HotSpot or OpenJDK, increasing the heap size to accommodate large datasets can result in longer GC pauses. These pauses occur because the garbage collector requires more time to manage the larger heap, which can negatively impact application responsiveness. One solution is to use a concurrent garbage collector, such as the one provided by Azul Zing , designed to handle larger heap sizes while reducing GC pause times. However, this approach may only scale well when the dataset is within the available main ...

Unveiling Floating-Point Modulus Surprises in Java

When working with double in Java, floating-point representation errors can accumulate, leading to unexpected behaviour—especially when using the modulus operator. In this article, we'll explore how these errors manifest and why they can cause loops to terminate earlier than anticipated. The Unexpected Loop Termination Consider the following loop: Set<Double> set = new HashSet<>(); for (int i = 0; set.size() < 1000; i++) { double d = i / 10.0; double mod = d % 0.1; if (set.add(mod)) { System.out.printf("i: %,d / 10.0 = %s, with %% 0.1 = %s%n", i, new BigDecimal(d), new BigDecimal(mod)); } } At first glance, this loop should run indefinitely. After all, the modulus of d % 0.1 for multiples of 0.1 should always be zero, right? Surprisingly, this loop completes after 2,243 iterations, having collected 1,000 unique modulus values. How is this possible? The full code is available on GitHub. Understanding Flo...

Thread Safety Issues with Vector and Hashtable

Considered legacy since Java 1.2 (1998), Vector and Hashtable remain prevalent in many Java applications. A common belief is that their synchronised methods render them inherently thread-safe. However, this assumption can lead to subtle concurrency problems that are often overlooked. Have you encountered unexpected exceptions when iterating over a Vector in a multi-threaded environment? Let’s delve into why this happens and how to address it. The Misconception of Thread Safety Both Vector and Hashtable synchronise individual method calls, leading many developers to assume that these classes are safe to use concurrently without additional synchronisation. While each method is thread-safe, combining multiple method calls can introduce race conditions if not properly managed. Are Iterators Thread-Safe? The Iterator is not thread-safe for most collections, including Vector . Iterators are designed to fail fast by throwing a ConcurrentModificationException when t...

Exceptional Exception, StackTrace extends Throwable

Exploring Surprising Properties of Extending Throwable in Java In Java, most developers are familiar with extending Exception or Error to create custom exceptions. However, directly extending Throwable can lead to surprising and potentially useful behaviours. In this article, we'll delve into the nuances of extending Throwable and explore practical applications that can enhance debugging and monitoring in Java applications. The example code is available here Extending Throwable At first glance, extending Throwable might seem unusual. Unlike Exception , which is checked, or Error , which is unchecked, Throwable itself can be extended to create a new checked throwable that is neither an exception nor an error. public class MyThrowable extends Throwable { } public static void main(String... args) throws MyThrowable { throw new MyThrowable(); // Must be declared or caught } In this example, MyThrowable is a checked throwable, and the compiler enforces that it mu...

StringBuffer is Dead, Long Live StringBuffer

When Java 5.0 was released on 30 th September 2004, it introduced StringBuilder as a replacement for StringBuffer in cases where thread safety isn't required. The idea was simple: if you're manipulating strings within a single thread, StringBuilder offers a faster, unsynchronized alternative to StringBuffer . This is an updated article from 2011 From the Javadoc for StringBuilder : This class provides an API compatible with StringBuffer , but with no guarantee of synchronization. This class is designed for use as a drop-in replacement for StringBuffer in places where the string buffer was being used by a single thread (as is generally the case). Where possible, it is recommended that this class be used in preference to StringBuffer as it will be faster under most implementations. Is StringBuffer Really Dead? You might think that StringBuffer has become redundant, given that most single-threaded scenarios can use StringBuilder , and thread safety often require...

What can make Java code go faster, and then slower?

It's well-known that the JVM optimises code during execution, resulting in faster performance over time. However, less commonly understood is how operations performed before a code section can negatively impact its execution speed. In this post, I'll use practical examples to explore how warming up and cooling down code affects performance. The code is available here for you to run Warming Up Code When code is executed repeatedly, the JVM optimises performance. Consider the following code snippet: int[] display = {0, 1, 10, 100, 1_000, 10_000, 20_000, 100_001}; for (int i = 0; i <= display[display.length - 1]; i++) { long start = System.nanoTime(); doTask(); long time = System.nanoTime() - start; if (Arrays.binarySearch(display, i) >= 0) System.out.printf("%,d: Took %,d us to serialise/deserialise GregorianCalendar%n", i, time / 1_000); } This code measures the time taken to execute doTask() over multiple iterations, printing...

Overly Long Class Names in Java or Geeky Poem?

In Java development, clear and concise naming conventions are essential for code readability and maintainability. However, sometimes, we stumble upon class names that stretch the limits of practicality. One such example is InternalFrameTitlePaneMaximizeButtonWindowNotFocusedState . But did you know that in Java 6, this class name was even longer? Within the Java 6 JRE, there's a class with an astonishingly lengthy name: com.sun.java.swing.plaf.nimbus.InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowNotFocusedState This mouthful appears to be the product of a code generator that needed to be reviewed, leading to redundant and cumbersome naming. Or is it a geeky poem buried in the code? InternalFrame InternalFrame Title Pane, Internal Frame Title Pane. Maximize Button Window, Not Focused State. The moral of the story is always check the readability/sanity of generated code. In this Hacker News Discussion another class was also consid...