- Bootstrp ClassLoader (bootstrap class loader)
The Bootstrp loader is written in C++ language. It is initialized after the JVM is started. It is mainly responsible for loading %JAVA_HOME%/jre/lib
, -Xbootclasspath
the path specified by the parameters, and the classes in %JAVA_HOME%/jre/classes.
Because it is written in C++, it cannot be accessed by Java code, but you can check whether a class has been loaded by the bootstrap class loader.
- Extensions ClassLoader (extension class loader)
Bootstrp Loader loads ExtClassLoader, and sets its parent loader (it is the parent loader instead of the parent class) as itself. This ExtClass Loader is written in java. It mainly loads all the classes directories under this path and the path specified by the system %JAVA_HOME%/jre/lib/ext
variable java.ext.dirs
. class library.
- Application ClassLoader (application class loader)
After Bootstrp Loader loads ExtClassLoader, it will load AppClassLoader and specify its parent loader as ExtClassLoader. Its function is to load the current application directory Classpath
and java.class.path
the class or jre file specified by the system property. It is also the default loader for Java.
We will write an article about the knowledge of ClassLoader later to deepen our understanding
==========================================================================
Java's memory is not just heap memory and stack memory.
1. Program Counter
In order to ensure that the program can continue to execute, the processor must have some means to determine the address of the next instruction. And the program counter does just that.
The program counter, also called the PC register, is a small memory space. In the virtual machine conceptual model, the bytecode interpreter works by changing the program counter to select the next bytecode instruction to be executed.
The multi-threading of JVM is realized by switching in turn and allocating processor execution time. Only one processor executes the instructions in a thread at a certain moment . In order to restore the correct execution position after thread switching, each thread will have an independent program counter, so the program counter is private .
If the method executed by the thread is not a native method, the program counter is saved at the address of the bytecode instruction being executed, otherwise the value of the program counter is empty. The program counter is the only data area in the JVM specification that doesn't have any OOM situations
2. Java virtual machine stack
Each Java virtual machine thread has a thread-private Java virtual machine stack. Its lifecycle is the same as a thread.
The Java virtual machine stack stores the state of the Java method call in the thread, such as local variables, parameters, return values, and intermediate results of operations.
A Java virtual machine stack contains multiple stack frames , and a stack frame is used to store information such as local variables, operand stacks, dynamic links, and method exits . When a thread calls a Java method, the virtual machine pushes a new stack frame into the thread's Java virtual machine stack. After the method is executed, the stack frame is popped from the Java virtual machine stack.
Two exceptions are defined in the Java Virtual Machine Specification:
-
If the stack capacity allocated by the thread request exceeds the maximum capacity allowed by the Java virtual machine, the Java virtual machine will throw a StackOverflowError, that is, the stack will explode.
-
If the JVM stack can be dynamically expanded, but cannot apply for enough memory when expanding, or when creating a new thread, there is not enough memory to create the corresponding JVM, an OutOfMemoryError exception will be thrown, that is, OOM
Because most JVMs are scalable, we see more OOMs than stack bursts.
3. Native method stack
The JVM may use C Stacks to support the Native language. This C Stacks is the native method stack.
It is similar to the JVM stack, except that the local method stack is used to support the Native method. If the Java virtual machine does not support the Native method and does not depend on the C Stacks, it does not need to support local development. The Jvm can freely implement the local method stack, for example, the HotSpot VM combines the local development and the Java virtual machine stack into one.
The native method stack also throws StackOverflowError and OutOfMemoryError exceptions.
4. Java heap
The Java heap is a runtime memory area shared by all threads. The Java heap is used to store object instances.
Almost all object instances allocate memory here. Objects stored in the Java heap are managed by the garbage collector, and these managed objects cannot be explicitly destroyed.
From the perspective of memory recovery, the Java heap can be roughly divided into the new generation and the old generation .
From the perspective of memory allocation, multiple thread-private allocation buffers may be divided in the Java heap.
An exception is defined in the Java Virtual Machine Specification: If there is not enough memory in the heap to complete the instance allocation, and the heap cannot be expanded, an OutOfMemoryError exception will also be thrown.
5. Method area
The method area is a memory area shared by threads, and is used to store the structural information of classes that have been loaded by the Java virtual machine. Including runtime constant pool, field and method information, static variables and other data. The method area is a logical part of the Java heap. It is also not physically contiguous, and you can choose not to implement garbage collection in the method area.
The method area is not equal to the permanent generation, just because the HotSpot VM uses the permanent generation to implement the method area. For other JVMs, such as J9 and JRockit, there is no such concept as the permanent generation.
If the method area does not meet the memory allocation requirements, the JVM will also throw an OOM exception.
6. Runtime constant pool
Not part of the runtime data area, but part of the method area.
As we saw in the previous Class file structure, the Class file not only contains the version number, interface, fields, etc. of the class, but also contains the constant pool.
It is used to store literals and symbol references generated during compilation , which will be stored in the runtime constant pool in the method area after the class is loaded.
The runtime constant pool can be understood as the runtime representation of the constant pool of a class or interface.
========================================================================
The creation of objects is something we often do, usually through the new instruction to complete the creation of an object, when the virtual machine receives a new instruction, it will do the following operations:
-
Determine whether the class corresponding to the object is loaded, linked and initialized
-
allocate memory for the object
After the class loading is complete, a block of memory will be allocated to the object in the Java heap Memory allocation is based on whether the Java heap is regular. There are two ways:
(1) Pointer collision, if the memory of the Java heap is regular, that is, all used memory is put aside, and free memory is put aside. When allocating memory, move the pointer in the middle to the free memory for a distance equal to the size of the object, so that the work of allocating memory is completed
(2) Free list, if the memory of the Java heap is irregular, a list needs to be maintained by the virtual machine to record which memory is available.
In this way, a large enough memory can be queried from the list to allocate to the object during allocation.
Whether the memory of the Java heap is regular or not depends on whether the garbage collector used has the function of compacting and sorting.
- Dealing with Concurrency Security Issues
Creating an object is a very frequent operation, so there are two ways to solve the concurrency problem:
(1) Synchronize the action of allocating memory space, such as using the CAS algorithm in the virtual machine and adding a failed retry method to ensure the atomicity of the update operation
(2) Each thread pre-allocates a small piece of memory in the Java heap. This piece of memory becomes the local thread allocation buffer. When a thread needs to allocate memory, it allocates memory on the TLAB of the corresponding thread. When a new TLAB is allocated, synchronization lock is only required at this time. Use the -XX:+/-UserTLAB parameter to set whether the virtual machine uses TLAB.
- Initialize the allocated memory space
Initializes the allocated memory, except for the object header, to a zero value
- Set the object header of the object
Store data such as the class of the object, the HashCode of the object, and the GC generation age of the object in the object header of the object.
The knowledge of the object header will be sorted out later
- Execute the init method to initialize
Execute init()
, initialize the member variables of the object, call the constructor of the class, and an object is created.
PS: From the above alone, we can know that creating an object will actually cause a certain cost, so after reading these things, will you easily go to the new object? Will you go to the new object in onDraw()? So please also consider object creation as a minor operation!
4.1 Heap memory layout of objects
We already know that the object is created, and the heap allocates space for the object, so how is the object laid out in the heap memory, and what does it look like? As mentioned in the previous section, what is the object header?
Taking HotSpot VM as an example, the layout of objects in the heap memory is divided into three areas:
- object header
The object header includes two parts of information, namely Mark Word and metadata pointer
(1) Mark Word: Used to store object runtime data, such as Hash Code, lock status flag , CG generational age, and locks held by threads
(2) Metadata pointer: used to point to the metadata of the target class in the method area, through which the specific type of the object can be determined. I will talk about it later
- instance data
Used to store various types of field information in objects (including those inherited from parent classes)
- Align padding
Alignment padding does not necessarily exist, it acts as a placeholder and has no special meaning.
The implementation class of Mark Word in HotSpot is that markOop.hpp
markOop is designed as a non-fixed data structure, which is to store as much data as possible in a very small space.
The markOop format of the 32-bit virtual machine is as follows:
//32-bit markOop
hash:25 ------------>| age:4 biased_lock:1 lock:2 (normal object)
JavaThread*:23 epoch:2 age:4 biased_lock:1 lock:2 (biased object)
size:32 ------------------------------------------>| (CMS free block)
PromotedObject*:29 ---------->| promo_bits:3 ----->| (CMS promoted object)
The interpretation of the data is:
- hash
object's hash code
- age
The generational age of the object
- biased_lock
Bias lock flag
- lock
lock status flag
- JavaThread*
Id of the thread holding the biased lock
- epoch
Bias timestamp
Mark Word is often used to study the status of locks. When I was doing my understanding of object locks, I also wrote about this kind of thing, but the angle is different. It is traced from the lock to the Mark Word, and here is traced from the Mark Word to the lock. , I won’t go into details about locks here, here are two articles: Several lock mechanisms in Java
Synchronized lock optimization
Here is a summary:
The startup of a process can generate a JVM, and there are multiple threads on a JVM. When the program is running, the heap on the JVM will allocate memory space for many objects.
When a thread wants to use an object on the heap, it will first access the Mark Word of the object to see if the lock, the class lock, and the object lock can be used (that is, whether it is used by another thread) ), if it can be used, use it, if not, spin/wait according to the state of the lock or ...
oop-klass is a model used to describe Java object instances, which is divided into two parts:
- OOP(Ordinary Object Pointer)
Refers to the ordinary object pointer, which is used to represent the instance information of the object.
- klass
klass is used to describe metadata
The oop-klass model is adopted in HotSpot. oop is actually a family. Many oop types are defined inside the JVM, as follows:
typedef class markOopDesc* markOop; //oop mark object
typedef class oopDesc* oop; //top parent class of oop family
typedef class instanceOopDesc* instanceOop; //Indicates a Java class instance
typedef class arrayOopDesc* arrayOopDesc*; //array object
typedef class objArrayOopDesc* objectArrayOopDes //reference type array object
typedef class typeArrayOopDesc* typeArrayOop; //basic type array object
Where oopDesc is the top-level parent class of all oops, and arrayOopDesc is the parent class of objArrayOopDesc and typeArrayOopDesc.
Both instanceOopDesc* and arrayOopDesc can be used to describe the object header.
The klass family is also defined:
class Klass; //parent class of the klass family
class InstanceKlass; //Describe the data structure of the Java class
class InstanceMirrorKlass; //Description java.lang.Class instance
class InstanceClassLoaderKlass; //Special InstanceKalss, do not add any fields
class InstanceRefKlass; //Describe the subclass of Java.lang.ref.Reference
class ArrayKlass; //Describe Java array information
class ObjectArrayKlass; //Describe the data structure of the reference type array in Java
class TypeArrayKlass; //Describe the data structure of the basic type array in Java
Among them, Klass is the top parent class of the klass family. ArrayKlass is the parent class of ObjArrayKlass and TypeArrayKlass.
It can be found that members of the oop family have a corresponding relationship with members of the klass family.
For example, instanceOopDesc corresponds to InstanceKlass. objArrayOopDesc corresponds to ObjeArrayKlass.
Let's take a look at the definition of oop's top-level parent class oopDesc:
class oopDesc {
friend class VMStructs;
private:
volatile markOop _mark;
union _metadata {
wideClassOop _class;
narrowOop _compressed_klass;
} _metadata;
// Fast access to barrier set. Must be initialized.
static BarrierSet* _bs;
…
}
oopDesc contains two data members: mark and _metadata.
The markOop
type of mark object refers to the Mark Word mentioned above.
metadata
It is a union body, where klass is an ordinary pointer and _compressed_klass
a compressed class pointer. These two are the metadata pointers in the object header. They all point to instanceKlass according to the corresponding relationship, and instanceKlass is used to describe metadata. instanceKlass inherits from klass
, let's take a look at the definition of klass:
jint _layout_helper; //Comprehensive descriptor of object layout
Symbol* _name; //class name
oop _java_mirror; //The mirror class of the class
Klass* _super; // parent class
Klass* _subklass; //The first subclass
Klass* _next_sibling; //The next sibling node
jint _modifier_flags; //modifier flag
AccessFlags _access_flags; //Access authority identification
You can see that klass describes the metadata. Specifically, it is the equivalent C++ type description of the Java class in the Java virtual machine.
In this way, instanceKlass inherited from klass can also be used to describe metadata.
Knowing the oop-klass model, we can analyze how the JVM finds the corresponding object instance through the object reference in the stack frame.
4.3 The life cycle of Java objects in the virtual machine
After the Java object is loaded into the virtual machine by the class, the Java object has 7 stages in the Java virtual machine:
- Creation stage
The specific steps in the creation phase are:
(1) Allocate storage space for the object
(2) Construction object
(3) Initialize static members from superclass to subclass
(4) Recursively call the constructor of the superclass
at last
In fact, there are only so many knowledge points in Android development, and there are still so many things to ask in the interview. So there are no other tricks in the interview, it just depends on how well prepared you are for these knowledge points. So, when you go out for an interview, just check which stage you have reviewed.
For the 2019-2021 high-frequency interview questions of Tencent, Toutiao, Ali, Meituan, ByteDance and other companies shared above , the blogger also organized these technical points into videos and PDFs (actually it took a lot more than expected Energy), including knowledge context + many details , due to limited space, the above is only a part of it in the form of pictures.
Android learning PDF+learning video+interview document+knowledge point notes
[Android mind map (skill tree)]
Knowledge is not systematic? There is also a mental map of Android advanced learning sorted out here, for your reference.
[Android advanced architecture video learning resources]
High-frequency interview questions**, the blogger also organized these technical points into videos and PDFs (in fact, it took a lot more effort than expected), including knowledge context + many details , due to limited space, the above is only in the form of pictures Show you a part.
Android learning PDF+learning video+interview document+knowledge point notes
[Android mind map (skill tree)]
Knowledge is not systematic? There is also a mental map of Android advanced learning sorted out here, for your reference.
[External link image transfer...(img-h9b4jCTW-1644995678352)]
[Android advanced architecture video learning resources]