JVM内存详解(jdk1.7、jdk1.8)

最近面试的头大,好久没面试了,发现自己这些基础一点的东西都忘得差不多了,面试只能说到个大概,面不过有点小气人。

一、jdk1.7和jdk1.8的模型

下图是java1.7的内存结构
java1.7的内存结构
下图是java1.8内存结构
java1.8的内存结构
上面2图分别是jdk1.7与jdk1.8的内存模型

jdk1.8的时候jvm有很大的改进:使用元空间(mate space)取代了永久代。虽然元空间逻辑上仍然可以视为方法区的一种实现,但是在jdk1.8的jvm里面却没有给予方法去单独的一块内存区域了。

在jdk1.7的版本开始,已经开始了一部分去永久代的工作。比如字符串常量池迁移到堆内存中。而1.8则更进一步,把方法区的运行时常量池等信息全部迁移到了本地内存(native memory)之中,因此jdk1.8的jvm内存划分如上图java1.8内存结构

二、分区解析

1.程序计数器

程序计数器是一块较小的内存空间,可以看作当前线程执行的字节码的行号指示器。

如果线程执行的是一个java方法,计数器记录的是正在执行的虚拟机字节码指令的地址;
如果线程执行的是一个Native方法,这个计数器值则为空。

2.java虚拟机栈

线程私有的,每个线程对应一个java虚拟机栈,其生命周期与线程共同进退。每个java方法在杯调用时就会创建一个栈帧,并将该方法入栈,一旦调用完成就出栈。
当所有栈帧都出栈后,线程也就完成了实名。在局部变量表存储了8中基本数据类型,对象引用类型和returnAddress的类型。

3.本地方法栈

与虚拟机栈所发挥的作用类似,区别在于java虚拟机时java方法服务的,而本地方法栈则是为虚拟机栈使用到的native方法服务的。

4.java堆

java堆时java虚拟机所管理的内存中最大的一块,java堆时被所有线程共享的一块内存区域,在虚拟机启动时创建,此区域唯一的目的就是存放对象实例。java堆时内存回收的主要区域(GC堆)。从内存回收的角度看,java堆可细分成为新生代和老年代。
在这里插入图片描述
堆内存如上分为:

老年代(堆的1/3)
新生代(堆的2/3)
	Eden区(新生代的8/10)
	Suivival 0区(新生代的1/10)
	Suivival 1区(新生代的1/10)

5.元数据区

元数据区取代了1.7版本的永久代。
元数据区和永久代本质上都是方法区的实现。
方法去存放虚拟机加载的类信息,静态变量,常量等数据。

6.直接内存

直接内存并不是java虚拟机运行时数据区的一部分,也不是java虚拟机规范中定义的内存区域。
jdk1.4引入了NIO,他可以使用Native函数库直接分配堆外内存。

三、java堆的新生代、老年代、永久代的关系

如上,新生代分为三个区域、一个eden区和2个Suivival区,它们之间的比例为(8:1:1),这个比例时可以修改的。

通常情况下,对象主要分配在新生代的eden区,少数情况下可能会分配到老年代中。

java虚拟机每次使用新生代中的eden区和一块Suivival(From),经过一次Minor GC之后,将Eden和Suivival(From)中还存活的对象一次性复制到另一块Suivival(To)空间上(这里使用复制算法进行GC),最后清理掉刚才的Eden区和Suivival(From)区空间。
将此时复制过来的Suivival(To)区内存活的对象年龄设置为1,以后这些对象在Suivival(To)区中熬过一次GC,他们的年龄就+1,直到某个对象的年龄(默认15)时,就会将这个对象移动到老年代中。

在新生代中进行GC的时,有可能遇到另一款Suivival(To)区没有足够空间存放上一次新生代收集下来的存活对象,这些对象将直接通过分配担保机制进入老年代;

Eden区

eden区位于java堆中的新生代区内,时新生对象分配内存的地方,由于堆时所有线程共享的,因此在堆上分配内存需要加锁。而Sun JDK为了提升效率,会为每个新建线程的eden上分配一块独立的空间由该线程独享,这块空间成为TLAB(Thread Local Allocation Buffer)。在TLAB上分配内存不需要加锁,因此JVM在给线程中的对象分配内存时,会尽量在TLAB上分配。如果对象过大或TLAB用完,则仍然在堆上进行分配。如果Eden区内存用完了,则会进行一次Minor GC(young GC)。

Suivival From 和 Survival To

Survival区与Eden区同属于java堆中的新生代区内。Survival区有两块,一块成为From区,另一块时To区,这两个区是相对的,在发生了一次Minor GC之后,From区和To区会互换。

在发生Minor GC时,Eden区和Survival From区内还存活的对象复制到Surval To区内,并清除Eden和Surval From区,此时使用标记复制算法处理执行GC。

Survival To区会把一些存活足够久的对象移至老年代。

老年代

老年代存放的都是存活时间比较久的,空间较大的对象,因此老年代使用标记整理算法

当老年代容量满的时候,会触发一次Major GC (Full GC),回收老年代内不在被使用的对象资源。

总结:

1.Minor GC(young GC)是发生在新生代中的垃圾收集,采用标记复制算法
2.新生代中每次使用的空间不会超过90%,主要用于存放新的的对象。
3.Minor GC每次收集后,Eden区和Survival From区都会被清空。
4.老年代中使用Full GC(老年代只会执行Major GC,但是在老年代执行Major GC之前,会先在新生代执行一次Minor GC,所以这里说是Full GC),老年代采用标记清除算法

【未完,准备将担保机制一起放进来,时间关系,先放个担保机制的链接】
担保机制:https://blog.csdn.net/kavito/article/details/82292035

参考:https://blog.csdn.net/s674334235/article/details/103106482
参考:https://blog.csdn.net/weixin_43847987/article/details/102294286
参考:https://blog.csdn.net/qq_19734597/article/details/80958817

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值