java内存模型分析
通过代码分析java内存模型,执行代码:
public class Person { String name; int age; public void show(){ System.out.println(name); } public static void main(String[] args) { Person p1=new Person(); p1.age=24; p1.name="张三"; p1.show(); Person p2=new Person(); p2.age=35; p2.name="李四"; p2.show(); } }
栈
java虚拟机的内存可以分为三个区域:栈,堆,方法区
1.栈描述的是方法执行的内存模型,每个方法被调用都会创建一个栈帧(存储局部变量,操作数,方法出口等)
2.jvm为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数,局部变量)
3.栈属于线程私有,不能实现线程间的共享
4。栈的存储特性是,后进先出
5.栈是由系统自动分配,速度快,栈是一个连续的内存空间
堆
1.堆用于存储创建好的对象和数组
2.jvm还有一个堆,被所有线程共享
3.堆是一个不连续的内存空间,分配灵活,速度慢
4.堆被所有线程共享,在堆的区域会被垃圾回收器作进一步换分,新生代和老年代
方法区也是堆
1.方法区是java虚拟机规范,可以有不同的实现
jdk7以前是永久代,jdk7去除类永久代,存储静态变量,字符串常量池
jdk8是元数据空间和堆的结合
2.jvm只有一个方法区
方法区实际也是堆,只是用于存储类和常量的相关信息
3.存储程序中永远不变或唯一的内容。(类信息classs对象,静态变量,字符串常量)
常量池主要存放常量:如文本字符创,final常量值
垃圾回收机制:
java 内存管理很大程度上是指是堆中对象的管理,包括对象空间的创建和释放
对象空间分配:使用new关键词创建
对象空间释放:将对象赋值null
垃圾回收过程
1.发现无用的对象
2.回收无用对象占用的内存空间
无用对象指的是没有任何变量引用该对象,不在使用的对象
回收算法:
1.引用计数器法
对重每个对象对应一个引用计数器,当有引用指向该对象,则计数器加1,引用失效时减1
,计数器为0时则被当做无用对象,进行回收。缺点,循环引用,相互引用对象时,无法识别
2.引用可达法
程序把引用关系看做一张图,从节点Gcroot开始寻找,引用对象,,查找完毕后,剩下的就是无用对象
垃圾回收模型:
不同的对象的生命周期是不一样的,因此不同生命周期的对象可以采用不同的回收算法,
年轻代,年老代,永久代
1,年轻代,所有新生成的对象首先放在Eden区,MinorGC会用于清理年轻代,EDEN区满了会触发Minorgc,清理无用对象,将有用对象复制到survivor1,survivor2中,然后以后的回收过程中在survivor1,survivor2之间相互复制,在年轻代中经历15次垃圾回收,对象仍然存活的复制到年老区
2.年老区
年老去中存放的都是一些生命周期较长的对象,需要启动MajorGC,进行回收
3.永久代用于存放静态文件
FullGC用于清理年轻代和年老代,成本高,会对系统产生影响,以下情况会触发FULLGC
当年老代被写满
永久代被写满
SYSTEM.GC被显示调用
4.上一次GC后heap的各<・)))><<分配策略动态变化
在对JVM调优过程中,很大一部分工作就是对于FullGC的优化