1 jvm的内存区域划分
jvm其实是一个java进程,进程会从操作系统申请一大部分内存区域,包括堆,栈和方法区
举个例子
t是一个引用类型所有他在栈上,new test()是个对象,对象本体在堆上,func()则是在方法区,这就是内存区域划分,详细可看下图
void func(){
test t = new test();
}
内存区域图
2 jvm的类加载机制
类加载把.class文件加载到内存,得到类对象这样的过程,而类加载的过程总结有5步,分别是加载,验证 ,准备,解析,初始化。从而可以引出一个经典模型,双亲委派模型。
1加载 找到。class文件,并且读文件内容
2验证 找到明确的数据格式。如下图
3准备,说白了就是给类对象分配空间
4解析 就是给字符串常量进行初始化
5初始化,就是给类对象进行初始化
类加载一般什么时候触发?
类加载整体是使用了懒汉模式,因此触发方式如下:创建了这个类的实例,使用了这个类的静态方法,使用了子类来触发父类加载。
双亲委派模型
jvm中有3个类加载器分别是bootstrap classloader,extension classloader,application classloader,下面是他们的关系图。其实可以想象成这样bootstrap是老板,extension是主管,application是员工。
3 jvm的垃圾回收策略
垃圾回收也就是GC是为了释放内存,防止内存泄露的问题,具体就是释放堆,也就是把对象给释放了。
第一步确认垃圾
首先java采用的是可达性分析而python等语言采用的是引用计数法
根据代码看得图
test t1 =new test();
test t2 = t1 ;
引用计数法会随着引用的增加,计算器就增加,引用的减少,计算器就减少,当计算器为0时,则就是垃圾,但是引用计数法有缺陷,浪费内存空间和存在循环引用问题
可达性分析就是把对象之间的引用关系,理解成了一个树形结构.从一些特殊的起点出发,进行遍历.只要能遍历访问到的对象,就是“可达”.再把"不可达的”当做垃圾即可如图
可达性分析,总的来说,就是从所有的roots的起点出发,看看该对象里又通过引用能访问哪些对象. 顺藤摸瓜的,把所有可以访问的对象都给遍历—遍.(遍历的同时把对象标记成"可达")
第二步释放垃圾
具体是采用了分代回收的思想
1标记清除,如图
2复制算法
3标记整理
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现