Focuses on the Time zone of the Java runtime, including Java heap, virtual machine stack, local method stack, method area, and program counters.

preface

The memory structure of the JVM was covered in the last article, “JVM Series 1: JVM Memory Structure,” but this is not the whole story.

Runtime data area

What is the runtime data region?

When a Java program runs, it allocates a separate memory area for the JVM, which in turn can be divided into a runtime data area. The runtime data area can be roughly divided into five parts:

Java Heap

A lot of people who do development, they pay special attention to the heap and the stack, is that another way to illustrate the importance of the heap and the stack?

In a word: stack tube running, heap tube storage. The virtual stack is responsible for running the code and the virtual heap is responsible for storing the data.

First of all, the Java heap has the following characteristics:

  • We store our new objects, not our basic types and object references.
  • Because of the large number of objects created, the garbage collector mainly works in this area.
  • The thread shares the area and is therefore thread unsafe.
  • OutOfMemoryError can occur.

In fact, the Java heap can also be divided into the New generation and the old generation, and the new generation can be further divided into Eden, Survivor 1, and Survivor 2. For the scale parameters, you can look at this graph.

For details, please refer to “[JVM Series 1] JVM Memory Structure”.

Virtual machine Stacks (JVM Stacks)

The Java virtual machine stack is also an area of focus for developers. Again, put the dry stuff in first:

  • The Java virtual machine stack is thread private. Each thread has its own virtual machine stack, which has the same life cycle as the thread.
  • The virtual Stack describes the memory model of Java method execution: when each method is executed, a Stack Frame is created to store information about local variables, operation stacks, dynamic links, method exits, and so on. Each method that is called until the execution is complete corresponds to the process of a stack frame in the virtual machine stack from the stack to the stack.
  • It holds the basic data types (Boolean, byte, char, short, int, float, long, double) and a reference to the object (the reference type, which is not the same as the object itself, but may be a reference pointer to the starting address of the object, depending on the virtual machine implementation). It may also point to a handle representing an object or some other location associated with that object) and the returnAddress type (which points to the address of a bytecode instruction).
  • There are two possible exceptions in this area: a StackOverflowError is thrown if a thread requests a stack depth greater than allowed by the virtual machine; If the virtual machine stack can be dynamically extended (most Of the Java virtual machines can be dynamically extended, although the Java virtual Machine specification also allows fixed length virtual machine stacks), an OutOfMemoryError will be thrown when sufficient memory cannot be obtained during the extension.

Native Method Stacks

The function of the local method stack is very similar to that of the virtual machine stack, except that the virtual machine stack performs Java methods (that is, bytecode) services for the virtual machine, while the local method stack serves the Native methods used by the virtual machine.

The language, usage mode, and data structure of the methods in the native method stack are not mandated in the VIRTUAL machine specification, so specific virtual machines are free to implement it. Some virtual machines (such as the Sun HotSpot virtual machine) simply combine the local method stack with the virtual machine stack. As with the virtual machine stack, StackOverflowError and OutOfMemoryError are thrown in the local method stack area.

What is Native Method? Simply put, a Native Method is an interface for Java to call non-Java code. A Native Method is a Java Method whose implementation is implemented in a non-Java language, such as C. This feature is not unique to Java. Many other programming languages have this mechanism. In C++, for example, you can tell the C++ compiler to call a C function by using extern “C”.

Method Area

The method area is also a focus area, with the following main features:

  • Threads share the area, so this is a thread unsafe area.
  • It is used to store data such as class information, constants, static variables, and code compiled by the real-time compiler that has been loaded by the virtual machine.
  • An OutOfMemoryError is thrown when the method area cannot meet memory allocation requirements.

Although the Java Virtual Machine specification describes the method area as a logical part of the Heap, it has an alias called non-heap, which is supposed to distinguish it from the Java Heap. For developers used to developing and deploying applications on a HotSpot virtual machine, many prefer to refer to the method area as the “Permanent Generation”, which is not essentially equivalent, so what’s the difference? A method area is a definition in the Java virtual Machine specification, which is a specification, while a permanent generation is an implementation, which is a standard and an implementation. After Java 8, however, there is no such thing as a permanent generation.

The Java Virtual Machine specification is very loose on this area, and in addition to not requiring continuous memory like the Java heap and having the option of being either fixed size or scalable, you can also opt out of garbage collection. Garbage collection behavior is relatively rare in this area, but it is not that the data enters the method area as “permanent” as the name of the permanent generation. The target of memory reclamation in this area is mainly for constant pool reclamation and type unloading. Generally speaking, the “performance” of the reclamation in this area is not satisfactory, especially for type unloading, the conditions are quite harsh, but the reclamation in this area is indeed necessary.

Program Counter Register

Program counter is very simple, presumably everyone is not a beginner in Java, also should understand a little thread and process concept? (Soul interrogation, you understand?) It’s okay if you don’t understand. Let me make it clear.

A process is the smallest unit of resource allocation. A thread is the smallest unit of CPU scheduling. A process can contain multiple threads. Now consider the following scenario.

At some point, thread A gets the CPU’s right to execute the internal program. But thread A’s program is not finished yet, and at some point the CPU loses execution rights to thread B. After thread A’s untiring efforts, the execution right of the CPU is recovered, so thread A’s program has to start from scratch again?

This is where the program counter comes in. Its function is to record where the current thread is executing. In this way, when a thread regains the CPU’s right to execute, it executes directly from the recorded location, and branches, loops, jumps, and exception handling all depend on the program counter. In addition, the program counter has the following characteristics:

  • Thread private, each thread has a program counter, so it is thread safe.
  • The only area where an OutOfMemoryError does not exist is probably where the designers felt it was unnecessary.

Code Example Analysis

In the Case of the Java heap, method area, and thread-only area (mainly the virtual machine stack), methods are executed with the thread, local variables of the original type and references are stored in the thread stack, and the object associated with the reference, such as String, is stored in the heap.

To better understand the above picture, let’s look at an example:

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Logger;
public class HelloWorld {
    private static Logger LOGGER = Logger.getLogger(HelloWorld.class.getName());
    public void sayHello(String message) {
        SimpleDateFormat formatter =  new SimpleDateFormat("dd.MM.YYYY");
        String today = formatter.format(new Date());
        LOGGER.info(today + ":"+ message); }}Copy the code

Let’s review what we’ve learned:

  • The heap stores our new objects, not basic types and object references;
  • The stack stores basic data types, references to objects, and the returnAddress type.
  • The method area stores data such as class information, constants, static variables, and code compiled by the real-time compiler that has been loaded by the virtual machine.

The data of this program is stored in memory as follows:

It can be seen that the data is stored as follows:

  • Java heap: Object HelloWorld, object SimpleDateFormat, object String, and object LOGGER;
  • Thread exclusive areas (mainly virtual machine stacks) :message references, formatter references, today references;
  • Method area: class information SimpleDateFormat, class information Logger, class information HelloWorld, method sayHello(), and all methods of class information.

Should the static Logger Logger, since it is a static variable, belong to the method section?

Welcome to more like, more articles, please pay attention to the wechat public number “Lou Zai advanced road”, point to pay attention, don’t get lost ~~