Local method stack, heap of JVM memory structure

Posted by Patrick3002 on Fri, 04 Feb 2022 18:28:02 +0100

3. Local Method Stack

The local method stack is java The virtual machine needs to provide memory space for some local methods when they are called, which refers to those that are not java How to write code, because
 Ours java Code has some limitations, it sometimes can't deal directly with the bottom level of our operating system, so it needs some help c or c++Write native methods to work with the operating system
 Underlying api To deal with, java Code can indirectly invoke some of the underlying functions through local methods, which run in memory called local method stacks.
How many local methods are there? The answer is very many, no matter some java In the base class library or in the execution engine, they all call these local methods

Object Inside Class clone()A method is a clone of an object, and you can see that its method statement is nativeļ¼Œsuch native There is no way to implement it.
Its method implementation is achieved by c or c++Language written, our Java The code calls the real indirectly through the local method interface c and c++It can be implemented in many ways.
such as Object In class hashCode()The method is local. Object Class notify()Methods and notifyAll()The method is also local,Object class
 Of wait()Method is also local

The purpose of the local method stack is to provide a memory space for the local method to run

4. Heap

The program counters, virtual machine stacks, and local method stacks that we talked about earlier have a common feature. They are
 Threads are private, and the heap we'll start explaining now and the method area that follows can be seen as yes
 Thread shared area, let's look at the definition of heap next.

4.1 Definition

Heap heap

  • With the new keyword, objects created use heap memory

Characteristic

  • It is shared by threads, and objects in the heap need to consider thread security.

    Previously we talked about virtual machine stacks in which some local variables are thread-private, as long as your local variables
     Do not escape the scope of the method; it is thread safe.
    But our heaps are different because the objects in the heap are generally thread-safe, because they are shared by threads, with exceptions, of course.
    We'll talk about
    
  • Garbage Collection Mechanism

    Objects that are no longer referenced in the heap are recycled as garbage to free up idle memory, rather than being blown up by objects created in the memory.
    

4.2 heap memory overflow

// Run the following code
import java.util.ArrayList;
import java.util.List;

/**
 * Demo heap memory overflow java.lang.OutOfMemoryError: Java heap space
 * -Xmx8m
 */
public class Demo06 {
    public static void main(String[] args) {
        int i = 0;
        try {
            List<String> list = new ArrayList<>();
            String a = "hello";
            while (true){
                list.add(a);
                a = a + a;
                i++;
            }
        } catch (Throwable e) {
            e.printStackTrace();
            System.out.println(i);
        }
    }
}

The results are as follows:

Let's analyze this case to see why it caused a heap memory overflow.
a Strings are incremental, while a Append all the way to list The tail of the set, continually turning hello String object added to list In a collection, and list Set its lifespan declared from it
 Start until catch In front of the block, it is a valid range, so it cannot be garbage collected, that is, the program has not yet reached it catch Before, it was always working
 So it's always valid, and the string objects inside it are appended to list Inside the collection, so these string objects are equivalent to someone using them, and they can't
 Is garbage collected, so as more and more string objects, it will take up our heap space, which is an analysis of our heap space overflow.
Next, let's talk about a parameter: -Xmx8m
 This parameter controls the maximum heap space, so now let's set the heap space to 8 m

When we set heap space to 8 m After that, we run the above program again

Sometimes when the memory is very large, it may not be easy to expose this memory overflow problem. It may eventually cause your memory to overflow over time, but because of your memory
 Larger, maybe you have been running for a short period of time, you think it is OK, because the heap memory is still enough in a short period of time, so to troubleshoot this kind of heap memory overflow problem, you'd better put your
 The heap memory is set slightly smaller, which may expose possible heap memory overflow problems as soon as possible.

4.3 heap memory diagnostics

Here are some heap memory diagnostics related tools that can be typed directly on the command line window

  1. jps tool
  • See which java processes are in the current system and display their process numbers.

Once we get the id of the Java process, we can view the java process heap memory usage using the jmap tool

  1. jmap tool
  • View heap memory usage jmap-heap process id
jmap You can only see its heap memory usage at a certain point in time. If you want to do a continuous monitoring of heap memory usage over time, you need to use one
 More complex jconsole Tools for monitoring.
  1. jconsole tool
  • GUI
jconsole Tools are graphical interfaces, and the first two tools are command line methods, and jconsole It is a multifunctional monitoring tool that not only monitors heap memory usage,
It can also monitor threads, cpu These can be achieved by jconsole To monitor, and it can also achieve this continuous monitoring, let's look at these tools in a few specific cases
 Their use.

Let's look at this case:

/**
 * Demo heap memory
 */
public class Demo07 {

    public static void main(String[] args) throws InterruptedException {
        System.out.println("1...");
        // Threads are sleeping for 30 seconds here to give us time to enter commands
        Thread.sleep(30000);
        // new 10M data
        byte[] array = new byte[1024 * 1024 * 10];  // 10 MB,   1K   1M   10M
        // Output 2... Indicates that the data has been new10M
        System.out.println("2...");
        // Threads are sleeping for 30 seconds here to give us time to enter commands
        Thread.sleep(30000);
        array = null;
        System.gc();
        // Output 3... Indicates that garbage collection has been performed
        System.out.println("3...");
        Thread.sleep(1000000L);

    }
}

First, let's run the program, then use the jps tool to see the process id of the java program we're running

Then we use the jmap-heap ThreadID command when the program outputs 1...to see how much heap memory is being used by the java program we're running

This is the jmap-heap 110540 command

Execute to 2, that is, after the new array 10M has been allocated heap space, let's monitor it again

Let's move on to 3, after the garbage collection, and we'll monitor it again

After reviewing the use of jps and jmap tools, let's take a look at the use of jconsole tools.

The window of the jconsole tool appears when you type jconsole on the command line

Let's then dynamically monitor heap memory usage during java program execution

First, let's look at output 1, where the heap memory usage is more than twenty M before the program starts running and the array is created.

A new array has been created at the time of program output 2, where the heap memory usage is over forty M. We can see that the heap memory usage is over ten M higher than that at output 1.

Finally, when the program output 3, the heap memory was more than 6M, we had already done garbage collection, and at this time, because the array reference was empty, the array was also recycled as garbage.

In addition, the jconsole window can view memory usage and cpu usage

Next, let's introduce another case to learn jvisualvm

case

  • Memory usage remains high after garbage collection

Let's run the following program

import java.util.ArrayList;
import java.util.List;

/**
 * Demonstrate viewing the number of objects heap dump dump (grab a memory snapshot)
 */
public class Demo08 {
    public static void main(String[] args) throws InterruptedException {
        List<Student> students = new ArrayList<>();
        for (int i = 0; i < 200; i++) {
            students.add(new Student());
        }
        Thread.sleep(1000000000L);
    }
}
class Student{
    private byte[] big = new byte[1024 * 1024];
}

First we look at the process id through the jps tool. From the following figure we can see that the process id is 11288

Use jmap-heap 112088 to see this thread's memory usage

We can see that a total of over 200 M M of memory was used

Next let's do a garbage collection using jconsole

jconsole The use of tools has already passed before, if you forget, you can turn over the previous knowledge.

Now let's look at memory usage again with the jmap tool, and we can see that the new generation does have a lot of memory recycled, but the older generation does have a lot

We're wondering why memory hasn't been recycled. Are some objects referenced all the time because of our programming mistake and can't be freed? Next, we'll introduce a tool, jvisualvm, which means to visualize the contents of a virtual machine.

We then used the heap Dump feature, which is a snapshot of the current state and a detailed analysis of its contents, which is not a feature of jmap and jconsole

Then we looked for the top 20 most memory-consuming objects

And these Student instances must be long-term, causing our garbage collection to fail to recycle

Next let's look at the java source code

Analysis and sorting are similar in real-world environments, so let's start with the heap Dump This feature grabs a snapshot of the memory and then we analyze the objects that use the most memory.
You can draw useful conclusions about which objects are taking up too much memory, then you can analyze and troubleshoot your original code.

Topics: Java JavaEE jvm intellij-idea