1. Java Memory Management
Java memory management involves managing the memory used by Java
applications. The JVM (Java Virtual Machine) is responsible for memory
allocation and garbage collection.
Heap Memory: Used for dynamic memory allocation. Objects are created in
the heap.
Stack Memory: Used for method execution and local variables.
Garbage Collection: Automatic memory management to reclaim memory
used by objects that are no longer referenced. Java provides several
garbage collectors (e.g., G1, Serial GC).
Memory Leaks: Occur when objects are no longer needed but are still
referenced, preventing garbage collection.
2. Concurrency and Parallelism
Concurrency is the ability of a program to manage multiple tasks at the
same time, while parallelism is executing multiple tasks simultaneously
(usually on multiple cores).
Java provides several tools for working with concurrency:
o Threads: Execute code concurrently in a multi-threaded
environment.
o Executor Framework: Manages thread pools efficiently, providing
various types of thread executors.
o Locks and Synchronization: synchronized blocks and methods help
prevent race conditions. Java provides the ReentrantLock class for
more advanced locking.
o ForkJoinPool: A framework that divides tasks into smaller subtasks
and executes them in parallel.
o CompletableFuture: Provides a more flexible and functional
approach to handling asynchronous tasks.
, Example (ExecutorService):
ExecutorService executor = Executors.newFixedThreadPool(4);
executor.submit(() -> System.out.println("Task executed"));
executor.shutdown();
3. Java Generics
Generics allow you to write classes, interfaces, and methods that operate
on objects of various types while providing compile-time type safety.
Using generics, you can create more flexible and reusable code by defining
type parameters in classes or methods.
Example (Generics):
class Box<T> {
private T value;
public void setValue(T value) {
this.value = value;
}
public T getValue() {
return value;
}
}
public class Main {
public static void main(String[] args) {
Box<Integer> intBox = new Box<>();
intBox.setValue(100);
System.out.println(intBox.getValue());
}
}