|
| 1 | +--- |
| 2 | +title: "Memory-safe code in Java" |
| 3 | +date: 2025-09-11 |
| 4 | +draft: false |
| 5 | +tags: [ "java", "kotlin", "jvm", "memory", "garbage collection" ] |
| 6 | +--- |
| 7 | + |
| 8 | +While Java's garbage collection handles most memory-related tasks automatically, developers still need to |
| 9 | +be aware of certain patterns and practices that can lead to memory leaks. This article explores common scenarios where |
| 10 | +memory management requires special attention and provides guidelines for writing memory-safe code in Java applications. |
| 11 | +Patterns here were observed while developing applets, but they should be applicable to any Java application. |
| 12 | + |
| 13 | +### Static Objects |
| 14 | + |
| 15 | +Static objects are treated as singletons and never collected from memory. They can be retained even if the app is |
| 16 | +destroyed on mobile platforms. If a static object holds reference to other objects, those objects will be retained as |
| 17 | +well. |
| 18 | + |
| 19 | +In contrast, static methods are fine to use, as long as they're not referencing other static fields in the class. |
| 20 | + |
| 21 | +### Stateless Lambdas |
| 22 | + |
| 23 | +For every lambda, JVM generates a synthetic class. If the lambda is stateless (i.e., doesn't hold any state outside |
| 24 | +its scope), JVM will make it a singleton that will be retained when the app is destroyed. |
| 25 | + |
| 26 | +Lambdas can be either capturing or stateless, and understanding this difference is crucial as it affects their behavior. |
| 27 | +For simplicity and consistency, if you're not sure, it's recommended to use anonymous classes instead of lambdas, as anonymous classes have |
| 28 | +more predictable behavior. |
| 29 | + |
| 30 | +### Anonymous Classes |
| 31 | + |
| 32 | +To avoid issues with stateless lambdas, it's better to use Anonymous Classes. Anonymous Classes are "first-class |
| 33 | +citizens" in Java and are treated as any other object. For listeners, it's safer to use Anonymous Classes. |
| 34 | + |
| 35 | +However, before JDK 18, any Anonymous Class always holds a reference to the enclosing class. If an anonymous class is |
| 36 | +retained (e.g., by a static field), it will cause the enclosing class to be retained in memory as well. |
| 37 | + |
| 38 | +### Inner Classes |
| 39 | + |
| 40 | +Inner classes should generally be static. Non-static inner classes should be used rarely as they always maintain a |
| 41 | +reference to their parent class. If you store data in a non-static inner class that persists for the entire lifetime |
| 42 | +(e.g., in a static variable), both the inner class and its parent class will be retained in memory. |
| 43 | + |
| 44 | +### Enums |
| 45 | + |
| 46 | +Enums are static by design. Only keep primitive values in enum constructors. For example, storing a resource reference |
| 47 | +in an enum constructor will cause the resource to be retained in memory, leading to memory leaks. Instead, |
| 48 | +store the resource path in the enum and use it to get the actual resource when needed. |
0 commit comments