Let's look into a brief description of each component:
Method Area: This contains all the class-level information, such as class name, parent class, methods, instance, and static variables. There is only one method area per JVM, and it is a shared resource.
Heap Area: This contains the information of all the objects. There is one Heap Area per JVM. It is also a shared resource. As Method Area and Heap Area are shared memory between multiple threads, the data stored is not thread-safe.
Stack Memory: JVM creates one runtime stack for every thread in execution and stores it in the stack area. Every block of this stack is called an activation record that stores methods call. All local variables of that method are stored in their corresponding frame. The stack area is thread-safe since it is not a shared resource. The runtime stack will be destroyed by the JVM up on termination of the thread. So, in the case of infinite loops of method calls, we might see StackOverFlowError, which is due to no memory in the stack for storing method calls.
PC Registers: These hold the addresses of current instructions under execution. Once the instruction is executed, the PC Registers will be updated with the next instruction. Each thread has a separate PC Registers.
Native Method Stacks: For every thread, a separate native stack is created. It stores the native method information. Native information is nothing but native method calls.