Memory / Runtime / Allocator - Go vs Java

Memory management, pointers, and profiling are fundamental aspects of efficient code. Let's consider three key concepts: slice backing array, pointer, and profiling (pprof / trace), and compare Go with Java.

1. Slice backing array

A slice in Go is a lightweight structure over an array: it holds a pointer to the array, length, and capacity.


arr := [5]int{1,2,3,4,5}
s := arr[1:4]      // {2,3,4}, holds a reference to arr
s[0] = 20
fmt.Println(arr)   // [1,20,3,4,5]
  

Tip: if you change elements of a slice, remember that it changes the backing array and can unexpectedly affect other slices.

“A slice in Go is not just an array, but a tool for safe memory handling that allows sharing and extending data without copying”

The Java equivalent is ArrayList or an array, but copying a slice does not change the original:


int[] backingArray = new int[]{1,2,3,4,5};
int[] slice = Arrays.copyOfRange(backingArray, 1, 4);
slice[0] = 20;
System.out.println(Arrays.toString(backingArray)); // [1,2,3,4,5]
  

2. Pointer / References

Go allows using pointers directly:


x := 10
p := &x
*p = 20
fmt.Println(x) // 20
  

Tip: pointer arithmetic in Go is dangerous—use it only where absolutely necessary. In most cases, slices and structs are sufficient.

In Java, all objects are passed by reference, while primitives are passed by value. Example:


Integer x = 10;
Integer y = x; // copy of the reference
// Changing an immutable object is not possible, but array or List objects can be modified via reference
  

3. Profiling (pprof / trace)

Go has built-in tools for CPU and memory profiling:


import _ "net/http/pprof"
go http.ListenAndServe(":6060", nil)
  

Java uses JFR, VisualVM, Mission Control:


// java -XX:+UnlockCommercialFeatures -XX:+FlightRecorder -jar app.jar
  

Tip: always enable profiling during development or staging to see real memory and CPU issues.

4. Summary Comparison Table

Feature Go Java
Slice / ArrayList Slice holds a reference to the array, len, cap ArrayList holds an internal array, copies do not change the original
Pointer / Reference Can be modified directly References to objects, primitives by value
Profiling pprof / trace JFR, VisualVM, Mission Control
Memory safety Garbage collector + unsafe capabilities GC + type safety

5. Conclusion and Recommendations

  • For Go: pay close attention to slices and pointers, profile with pprof.
  • For Java: use references and built-in collections, profiling through JFR/VisualVM.
  • General principles: understanding runtime, allocator, and reference model helps write efficient code and avoid unexpected side effects.

“Knowing how slices, pointers, and garbage collection work is critical to building high-performance and safe applications. In Go and Java, the approaches are different, but the concept of memory management and profiling is the same”


🌐 На русском
Total Likes:0

Оставить комментарий

My social media channel
By sending an email, you agree to the terms of the privacy policy

Useful Articles:

Channel direction and select patterns in Go vs Java | Patterns, idioms, and best practices in Go
← Related articles: Context, propagation and cancellation patterns in Go vs Java | Patterns, idioms and best practices in Go 1. Channel direction — channel directions In Go, channels can be one-w...
Memory / Runtime / Allocator - Go vs Java
Memory management, pointers, and profiling are fundamental aspects of efficient code. Let s consider three key concepts: slice backing array, pointer, and profiling (pprof / trace), and compare Go wit...
Analyzing: array, slice, map, zero value - in Go vs Java | Types - Language
Series: Go for Java Developers This article opens a series of materials about the Go language for developers who are already well acquainted with Java. We will compare the approaches of the two langu...

New Articles:

Zero Allocation in Java: what it is and why it matters
Zero Allocation — is an approach to writing code in which no unnecessary objects are created in heap memory during runtime. The main idea: fewer objects → less GC → higher stability and performance. ...
Stream vs For in Java: how to write the fastest code possible
In Java, performance is often determined not by the "beauty of the code," but by how it interacts with memory, the JIT compiler, and CPU cache. Let s analyze why the usual for is often faster than Str...
Compiler, Build, and Tooling in Go and Java: how assembly, initialization, analysis, and diagnostics are organized in two ecosystems
This article is dedicated to a general overview of how the compiler, build, and tooling practices are arranged in Go, and how to better understand them through comparison with Java. We will not delve ...
Fullscreen image