- jvm内存模型
主要分为运行时区域和非运行时区域
1.1非运行时区域
-
- 类加载系统
当程序需要执行硬盘上的字节码文件时,类加载器(classloader)会将其加载到内存中并进行初始化。
比如说创建一个对象(new)、访问或引用一个对象中的静态变量或者静态方法、反射、初始化一个类的子类时,就需要对类进行初始化和加载,这些是主动加载。
但如果是被动加载,比如说访问类中的静态常量或者以对象作为元素创建集合就不会对类进行初始化,这就是主动加载和被动加载的区别。
-
-
- 类加载过程
-
加载:将字节码文件从硬盘结构转为内存结构
链接:
验证:验证所加载的字节码文件是否会对jvm造成破坏,格式语法是否正确
准备:为静态变量进行初始化赋值,但并不会为静态常量赋值
解析:将符号引用(文件中的逻辑引用)转为直接引用(实际内存地址值)
初始化:初始化静态成员变量
-
-
- 类加载器以及其分类
-
类加载器是加载类的类
启动类加载器:用c语言编写的
其他类加载器:java编写
扩展类加载器:负责加载\jre\lib\ext目录下的类,包含应用程序类加载器
应用程序加载器:负责加载程序中的类
-
-
- 双亲委派机制
为了确保类加载的正确性、安全性,在类加载时,采用双亲委派机制;当需要加载程序中一个类时,会先让类加载器的父级去加载,直到最顶级的启动器类加载器;如果父级找到了返回使用,如果依然没找到就委派给子级去加载,找到了就返回;如果所有类加载器都没找到,报类找不到异常。
**优点:**安全,避免了自己写的类替换了系统中的类,避免类重复加载。
- 双亲委派机制
为了确保类加载的正确性、安全性,在类加载时,采用双亲委派机制;当需要加载程序中一个类时,会先让类加载器的父级去加载,直到最顶级的启动器类加载器;如果父级找到了返回使用,如果依然没找到就委派给子级去加载,找到了就返回;如果所有类加载器都没找到,报类找不到异常。
- 本地方法栈
-
这里面会装由native修饰的方法,这些方法基本上都不是java写的,而是系统层面用c或其他语言编写。
-
- 执行引擎
用于执行本地方法栈中的方法、字节码文件,修改程序计数器中的数值等
1.2运行时区域
-
- 堆区
主要用于存储字符串、对象信息,jvm内存调优主要是这一块。
-
- 栈区
存储线程私有的信息,内存地址
- 当一个线程开始执行方法的时候,它的专属栈区就会划分出一块内存作为方法栈(栈帧),每个栈帧又划分为局部变量表(记录变量符号)、操作数栈(作为临时内存,记录需要进行运算操作的数据,当运算完毕,将数据赋值给局部变量表的变量符号)、动态链接(根据符号找到内存地址值)、方法出口这几个基本区块。
- 元空间
- java1.8之前称为方法区,之后改为元空间。存储字节码文件
- 程序计数器
- 记录当前线程执行指令到哪的行数。当多个线程抢占CPU时间片时,需要记录当前被抢线程执行到哪,方便下次抢回CPU使用权时继续执行。这也是线程私有的部分。
- 栈区
存储线程私有的信息,内存地址
标签:初始化,java,字节,--,虚拟机,线程,内存,加载 From: https://www.cnblogs.com/unhabby/p/16736190.html