Java equivalents of malloc(), new, free() and delete

C++ provides a few ways to allocate memory from the heap1:

In either case, C++ also requires the programmer to free up allocated memory once it is no longer needed (or else have a memory leak). The free() function recovers memory allocated via malloc(). The delete keyword deconstructs an object, which could involve some cleanup code in addition to deallocating the memory. To understand the Java equivalents of these various operations, it's worth first seeing a general overview of memory management in the two languages, which we'll do in the next section. Then in the following sections, we'll look at details of each of the four abovementioned operations in turn.

The basics: comparing memory management in C++ and Java

For a C++ program to function correctly, the programmer is effectively required to allocate memory in one of the above ways if it is to escape the function in which it is allocated. For example, the following is incorrect:

// Warning: do not try this at home!
char *makeString() {
  char[] str = "Wibble";
  return str;

The problem is that str will be allocated off the stack, and this memory will become invalid (or at least, liable to be overwritten) when the function exits. To correct the above function, we need to make it allocate the space for the string via malloc() (or new):

char *makeString() {
  char *str = (char *) malloc(200);
  strcpy(str, "Wibbly");
  return str;

It would then be up to the caller to call free() on the resulting string as and when it had finished with it. Things pretty much have to be this way in C/C++: in all but the most trivial cases, it would be virtually impossible for the compiler to determine that an object was "finished with". (Consider, for example, that in C/C++ any pointer could be made to point to that object at some arbitrary moment.)

In Java, things are a little different. The JVM sees Java objects as "objects", not simply as accesses to memory locations. And indeed, Java doesn't allow access to any memory that isn't part of an object. If there are no more references to a particular object, the Java Virtual Machine (JVM) knows that there won't be some pointer lurking about waiting to access that object's memory space. This all means that in Java, memory allocation can be managed much more by the runtime system:

We've said that the JVM can decide to allocate memory for an object on the stack (if it determines this is safe and desirable). But this is really an implementational detail. In terms of how it looks to the programmer, in Java, all objects are effectively allocated from the heap.

Next: functions and operators

With this introduction in mind, we'll look at the effective equivlents of the C++ memory management keywords and functions mentioned:

1. A heap is a block of contiguous memory set aside that can have smaller portions of it allocated out as and when necessary. In the eyes of the programmer, in both C/C++ and Java, we usually talk about allocating from "the heap" in an abstract way. But in neither language is there usually one single block of contiguous memory from which all allocations are made. For performance reasons, good malloc() implementations will internally manage several heaps (e.g. one for large allocations, one for small allocations...); and modern JVMs often have several heaps internally. In most of this discussion, we'll continue to use the term "the heap", as that is how memory is presented to the programmer.
2. The only slight exception in Java is that using the Java Native Interface (JNI), it possible to wrap a direct ByteBuffer around a block of memory allocated from native code (whose address is thus known). But the memory address still isn't exposed at the Java level, and from Java, the memory must still be accessed via that ByteBuffer object.

If you enjoy this Java programming article, please share with friends and colleagues. Follow the author on Twitter for the latest news and rants.

Editorial page content written by Neil Coffey. Copyright © Javamex UK 2021. All rights reserved.