java内存管理
2017-03-03 20:14:03 0 举报
Java内存管理是Java虚拟机(JVM)自动完成的,它包括堆内存的分配和回收、栈内存的分配和回收等。在Java中,程序员不需要手动管理内存,JVM会根据程序的需要自动分配和回收内存。这种自动内存管理的方式可以有效防止内存泄漏和溢出等问题,提高了程序的稳定性和可靠性。 Java内存管理主要包括以下几个部分:堆内存、栈内存、方法区、本地方法栈和程序计数器。其中,堆内存主要用于存储对象实例,栈内存用于存储局部变量和方法调用,方法区用于存储类信息、常量、静态变量等,本地方法栈用于支持本地方法调用,程序计数器用于记录当前线程执行的位置。
作者其他创作
大纲/内容
空闲列表:VM维护一个空闲内存的列表分配
优劣势1中reference不用被修改2的访问速度快,节省了一次指针定位开销Sun的HotSpot使用的是2方法
方法区
虚拟机方法栈的本地变量表中放置了指向堆中对象的reference
垃圾回收算法
大的对象分配的时候直接进入该区,长期存活的对象进入该区域。对象每经过一次MGC长一岁。当MGC前会判断是否有担保失败的风险,如果有那么发动一次FGC,否则直接MGC。担保的意思就是当MGC发动的时候如果Survivor块不够用,那么会将一部分对象提前进入老年代,如果新生代的存活下来的对象比老年代剩余空间多,那么就可能导致担保失败。
动态链接
对象类型数据
对象
多线程收集,标记-清除:并发GC,初始标记,并发标记,重新标记,并发清除
对象实例数据
方法2:refrence直接访问对象
Survivor1
方法返回地址
句柄池
CMS垃圾收集器
1.Parallel Old只能和Parallel Scavenge搭配2.CMS可以和除了Parallel Scavenge搭配3.Serial Old 都能搭配4.G1是新生老年通吃
本地方法栈:本地方法的调用栈
CMS
Survivor2
线程的内存结构完全相同,并且内部的内存都是私有的
多线程收集,标记-清除-复制:GC时需要停止JVM所有线程
方法区溢出:方法区中类的数量太多,导致无法继续加载类的时候溢出。如CGLib等动态生成字节码的技术
单线程收集,标记-清除-复制:GC时需要停止JVM所有线程
判断常量池中是否有该类的符号引用
加载该类
标记-整理:此算法用于老年代,一边清理死亡对象一边整理内存碎块
对象实例数据指针
Java堆
创建对象之后
实例池
标记-清除-复制:将所有被标记死亡的对象的内存清理掉,会出现内存碎片的问题,所以此时会有一个复制算法用于上图的新生代
多线程收集,标记-整理:并发GC初始标记,并发标记,最终标记,筛选回收
Serial、ParNew等垃圾收集器
创建一个不是数组和Class的普通对象
实例数据:程序员使用的各种数据
Eden:大块,每次MGC后将剩下的对象复制到空的Survivor中,同一时间只有一个Survivor在使用
指向
除了对象头,其他内存空间都赋0
是
例如
对象2类型数据
没有
虚拟机栈或本地方法栈溢出:栈的深度大于虚拟机允许的深度、扩展栈的时候无法申请到足够内存
描述方法执行的内存模型:每调用一个方法就创建一个方法帧。1.局部变量表:放置了当前方法的中所有的基本数据+对象引用,long和double占两个局部变量空间,该表空间分配在编译时完成,在进入每个方法时所需要分配的空间是完全确定的,所以在运行期间表的大小不会改变。2.操作数栈:存放的数据类型和空间分配与1相同,jvm使用栈代替寄存器储存在方法运行中需要用到的数据。4.一个方法有两种方式结束,1.正常结束 2抛出异常结束。当方法结束需要将本方法出栈并返回到方法调用的位置,将返回值压入调用者的操作数栈中。
有
多线程收集,标记-清除-复制,关注吞吐量:GC时需要停止JVM所有线程
可达分析:以一个Root对象为起点(栈帧中的局部变量、类中静态属性、常量对象、Native方法),以一个引用为一条边,创建一个图,若有对象不可达,那么即为可能死亡对象。缺点是:算法消耗大
总的来说
ParNew
程序计数器:线程私有,指示当前线程运行到的字节码行号
堆
对象的访问
main线程
共享所有线程共享,包含了类信息、常量、静态变量等编译后的代码
引用计数:有几个引用指向堆中对象就算几个计数,当计数为0说明对象死去。缺点是:如果有n个对象产生一个环,那么虽然其中对象可能都死去但是不能被销毁
程序员的初始化操作
指针碰撞:分配内存只需临界处的指针移动
常量池:放置字面常量
对象类型数据指针
新生代
线程2
方法取
线程3
进程
对象2
Parallel Old
老年代
从堆中划分内存:判断堆中的内存是否规整
操作数栈
前一方法帧
ParallelScavenge
Serial OldMSC
Serial
对象头:储存hash码、GC年龄、锁状态、线程持有锁、指向该对象类的指针等数据。
各种运行时数据区的OOM
否
句柄,同上
线程4
MCG是新生代的GC,FGC是老年代的GC,MGC比FGC快10倍以上。
当前方法帧
虚拟机栈
单线程收集,标记-整理:GC时需要停止JVM所有线程
局部变量表
判断对象是否死去
一个对象的内存布局
多线程收集,标记-整理,关注吞吐量:GC时需要停止JVM所有线程
垃圾回收算法的实现
堆溢出(java heap space):创建了过多对象,堆经过GC之后还是没有足够的空间
G1
垃圾收集器
对齐填充:不是必须的,只是VM用来8位对齐的占位符
方法1:reference指向句柄
对象是否死亡:经过了上面两个方法的筛选,被宣告死亡的对象还要进过两次标记:1.判断finalize()是否需要被执行(如果对象没有覆盖该方法或者其已经执行过那么就不需要执行)2.再次标记如果此时该对象还没逃脱,那么就会被回收。
常量池溢出:过多的String
0 条评论
下一页
为你推荐
查看更多