Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →To reduce Java garbage-collection overhead, avoid unnecessary collection growth, process large inputs as streams, and consider immutability where it fits your design. These techniques can reduce allocation pressure or the work a collector must do, but none guarantees shorter pauses in every application. Measure performance under representative load before changing JVM settings.
What garbage collection affects
The garbage collector allocates memory, identifies objects that are still in use, and reclaims memory held by unreachable objects. HotSpot uses techniques including generational collection, aging, parallel or concurrent work, and compaction to manage that work efficiently. The right balance depends on the application and its performance goals.
Look for three practical warning signs: objects continuing to accumulate after collections, stop-the-world pauses that interrupt application threads, and CPU spikes associated with GC activity. A high GC count alone does not establish a problem; the effect on responsiveness and throughput matters.
Measure before changing code or JVM settings
Track both throughput and latency. Oracle defines throughput as the share of total time not spent in GC; latency reflects how responsive the application is. Pauses can harm responsiveness even when the application completes substantial work overall.
- Allocation rate and the frequency of young- and old-generation collections.
- Pause-duration percentiles, not only an average that can conceal long pauses.
- Heap occupancy, promotion into older generations, and peak live-set size.
- CPU consumed by GC alongside application throughput and response times.
Oracle’s JDK 16-era HotSpot GC Tuning Guide gives a scale example: at 32 processors, spending 1% of time in GC can correspond to more than 20% throughput loss; at 10%, the example reports more than 75% loss. These are illustrative model figures, not predictions for an individual workload. See Oracle’s HotSpot GC Tuning Guide.
1. Predict collection capacity
Many Java collections use backing arrays. When a collection outgrows its current capacity, it may allocate a larger array and discard the old one. If you have a reasonable estimate of the number of elements, providing an initial capacity can avoid some resizing and temporary allocation.
Rank #2
When it helps
Capacity estimates are most useful for collections populated in a known batch, such as building a list from a record count or assembling a map from a bounded input. Use the relevant collection constructor or factory that accepts an initial capacity, and choose an estimate based on the expected number of entries—not an arbitrarily huge value.
Trade-offs
Overestimating capacity can retain more memory than needed, increasing the live set. Underestimating it may still allow resizing. Capacity planning is an allocation optimization, not a substitute for checking whether the collection itself is necessary or whether its contents remain reachable longer than intended.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
2. Process large inputs as streams
Reading a whole file or network payload into a byte array creates a large temporary object. The array can increase peak heap use and may be too large for available heap. When the downstream API supports it, pass an InputStream directly to a parser or consumer so processing can proceed in bounded chunks rather than retaining the entire input at once.
Choose streaming when
- Inputs may be large or their size is not known in advance.
- The operation can consume records or chunks incrementally.
- You do not need random access to the complete payload.
Account for the processing window
Streaming does not make memory use zero: buffers, parser state, and application-level objects still consume heap. Keep the processing window bounded and release references to consumed data. If the algorithm genuinely requires the complete input in memory, streaming may not remove the dominant live-set cost.
Rank #4
3. Use immutable objects where they fit
An immutable object cannot have its non-primitive fields changed after construction. The 2020 DZone article argues that older immutable objects can reduce work during collection of a younger generation because their references cannot change; fewer objects or pages to scan can mean shorter GC cycles and pauses. See DZone’s 2020 article on three GC techniques.
Apply immutability for correctness first
Immutability can simplify reasoning about shared state and prevent accidental mutation, independently of GC. For this technique, assess whether the objects are genuinely immutable, how they are allocated and retained, and whether the target collector and workload show a measurable benefit. The effect is not a universal guarantee: object layout, reachability, collector behavior, and allocation patterns matter.
Free tools Windows power users keep installed
One-click scans. No signup required.
Best Value
How to choose a collector and heap settings
Java provides collectors with different trade-offs, and a runtime default is not necessarily ideal for every workload. Start by defining whether the application prioritizes throughput or responsiveness. Throughput-oriented settings may tolerate longer pauses; low-pause choices can use more CPU or reduce total throughput. Heap size, young-generation sizing, and pause-time targets can also shift collection frequency and pause behavior.
Oracle identifies total available memory and the proportion of the heap devoted to the young generation as important factors in GC performance. Avoid copying a flag set without validating it against the application’s JDK version and workload. Use the Oracle tuning guide for the relevant JDK generation as a starting point, then compare results under representative load.
Quick Recap
A practical tuning sequence
- Establish a baseline: record latency, throughput, allocation rate, heap occupancy, GC CPU, collection frequency, and pause percentiles under representative traffic.
- Address avoidable allocations: pre-size collections where counts are predictable and stream inputs when consumers can process them incrementally.
- Review object design: use immutability where it improves correctness and evaluate any GC benefit with measurements.
- Test collector or heap changes separately: change one meaningful setting at a time and compare against the same workload and JDK.
- Keep changes only when outcomes improve: confirm that gains in pauses or throughput do not come with unacceptable CPU use, memory footprint, or application behavior.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

