JVM 内存模型是什么?**
(1)JVM 内存模型共分为5个区:Java虚拟机栈、本地方法栈、堆、程序计数器、方法区(元空间)
(2)各个区各自的作用:
a.本地方法栈:用于管理本地方法的调用,里面并没有我们写的代码逻辑,其由native修饰,由 C 语言实现。
b.程序计数器:它是一块很小的内存空间,主要用来记录各个线程执行的字节码的地址,例如,分支、循环、线程恢复等都依赖于计数器。
c.方法区(Java8叫元空间):用于存放已被虚拟机加载的类信息,常量,静态变量等数据。
d.Java 虚拟机栈:用于存储局部变量表、操作数栈、动态链接、方法出口等信息。(栈里面存的是地址,实际指向的是堆里面的对象)
e.堆:Java 虚拟机中内存最大的一块,是被所有线程共享的,几乎所有的对象实例都在这里分配内存;
(3)线程私有、公有
a.线程私有:每个线程在开辟、运行的过程中会单独创建这样的一份内存,有多少个线程可能有多少个内存
Java虚拟机栈、本地方法栈、程序计数器是线程私有的
b.线程全局共享的
堆和方法区
(4)栈虽然方法运行完毕了之后被清空了,但是堆上面的还没有被清空,所以引出了GC(垃圾回收),不能立马删除,因为不知道是否还有其它的也是引用了当前的地址来访问的
GC过程
首先有一个GCRoot不会清除栈,本地栈,方法区中的,还有被他直接或间接引用的对象。
关于GC算法有几种
1.标记清理,对于需要清楚的进行标记,缺点是里面有碎片
2标记整理,,把清楚完了往前移一位,缺点是代价太大了
3复制,把需要的复制过去,不需要的留下,缺点是要2倍的内存。
4分代,首先把区域分为Yong区和Old区Y区里面有E区和s0,s1区对象创建的时候会先在E区,E区快满的时候会触发GC,YongGC采用复制算法把删除的打赏标记不需要的就放到s0去,里面s0区s1区E区比例差不多是1:1:8,之后会把S0区保留下来把E区和S1区删除之后就会S0和S1交替使用
关于Old区每一次YongGC回收完年龄都加1,Old区存放年龄默认到6(CMS默认其他15)的时候还有一些很大的对象,old区回收一般回合Yong一起回收,叫fullGC,这时java程序会全力的区垃圾回收,一般用到标记清理和标记整理
经典的垃圾收集器
年轻代的串行的Serial,PawNew就是多线程的Serial,PS他关注吞吐率(一段时间内能持续提供服务的时间)
这些对应的老年的收集器Serial old ,CMS,Paralled Old
CMS
首先会有初次标记,标记GCroot直接引用的对象这是Stop the word
然后是并发标记,标记所有的old对象,他是和用户线程一起并发执行的,所以可能一开始是不被清理的之后会被清理
第三步是重新标记,修正第二步的
第四步并发清理,标记清理算法
老年代中只有CMS是标记清理算法,其他的两个都是标记整理算法。
G1垃圾回收器
变成了棋盘状的内存结构,一个Region大概是1M到32M总共大概是2000个左右
之后讨论几种情况如果对象大小大于0.5个Region小于一个Region,讲直接放到Old区标记成为H。
大于一个Region将存放于多个H区,H区是O区的一种
Region
里面有一个特殊的结构Rset,这个作用是记录其他Region引用当前Region的。
还有一个是Cset本次GC所要清理的Region的集合
g1清理过程mixGC
1.初次标记,标记GCRoot对象,还有对象所在的Region(RootRegion)会进行SWT工作。
2.RootRegion扫描Old区中的Rset,有就标识出来
3.并发标记,同CMS,只不过遍历范围更小。
4.标记,同CMS,只不过用SATB会SWT
5.清理,复制清理会SWT,只选择垃圾较多的Region
碰到的一些问题*\