浅谈JVM内存结构

JVM内存结构

1.概述


从大角度来看,JVM内存分为两部分,一部分为线程私有的,是我们所不能操作的,还有一部分是所有线程共享的,之后我们对JVM调优也就是调的这一部分。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dXJTb2PD-1603241610397)(/Users/luca/MarkText-img-Support/JVM内存结构1.png)]

2.线程私有区

2.1 概述


线程私有部分都是一段连续的内存,速度快,但容量小,用户不可操作。下面是线程私有区的详细图。(现在里面已经有了一个math类)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BZRBm3Kr-1603241610399)(/Users/luca/MarkText-img-Support/JVM内存结构2.png)]

2.2 程序计数器


一块较小的内存空间,用于标记当前线程所执行字节码的行号。

这一张图片是使用javap -v 对.class文件反汇编出的,图中红色框内的就是程序计数器的标记了。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KO8Mc4Xf-1603241610401)(/Users/luca/MarkText-img-Support/JVM内存结构3.png)]

2.3 虚拟机栈


  1. Java 虚拟机栈是由一个个帧栈组成。每个线程都有自己的栈,栈中的数据都是以栈帧的格式存在。

  2. 栈帧是一个内存区块,是一个数据集维系着方法执行过程中的各种数据信息

  3. 每个方法执行时会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。

  4. 当方法调用时,栈帧入栈,方法结束时,栈帧出栈。

  5. 局部变量表的所需的内存空间在编译期间完成分配,运行时不会改变大小。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cbB4iCeb-1603241610403)(/Users/luca/MarkText-img-Support/20200617115923958.png)]

2.4 本地方法栈

这个不多讲,与java几乎没有什么关系了。

3.线程共享区

3.1概述


线程共享部分分配的内存一般都比较大,因为有垃圾回收机制的影响,所以方法区,堆不是连续的内存。它是用来存东西的。它是我们可以控制的区域,意味着我们之后堆JVM调优就是调这一块。

3.2方法区(Method Area)(永久带/持久带,元空间)


在JDK1.8前,也叫永久带/持久带,JDK1.8后由于oracle把sun收购了,为了整合两款虚拟机,所以改为元空间。

所有定义方法的信息都保存在该区域,静态变量,常量,类信息,运行时常量池都在这个地方。虽然它是一个堆的结构,但为了区别于堆区,所以又一个别名叫非堆(None-heap)

这个不叫堆外内存 (堆外内存不是 JVM 运行时数据区 Runtime Data Area 的一部分,这部分内存区域直接被操作系统管理。

通常我们使用 java.nio.DirectByteBuffer 对象进行堆外内存的管理和使用,它会在对象创建的时候就分配堆外内存。)

JAVA堆外内存的简介 - 简书

3.3堆

3.3.1 概述

几乎所有的对象都放在堆里,当然可以用Native 方法创建堆外内存,把一些对象放到堆外内存中,而堆外内存其实就是方法区。堆是垃圾收集器主要管理的区域

为了方便回收,在堆里面的内存划分用到了分代。分为:

新生代(1/3),老年代(2/3)。新生代下面又分了 Eden,s0(From),s1(To)(这两个在survivor下) 比例为8:1:1.

3.3.2 Eden

西方文化里的伊甸园,人类出生的地方,所以一个新生的对象都会放到Eden区,除非这个对象太大了,太大会直接放到老年代。当Eden区放满了之后,就会进行回收。进行的是youngGC算法

3.3.3 回收算法初体验

回收的话在一般情况下只有两种:youngGC,只回收年轻代,FullGC,全部回收(包括元空间)。当然在CMS收集器中有OldGC。任何虚拟机所有的一个垃圾回收机制都有一个STW(Stop The World),在这个区间内,所有的用户线程停止,专门来执行垃圾回收线程,这也是Java虚拟机想解决,但又解决不了的问题。但youngGC的STW非常很短,短到让人感觉不到,所以一般我们指的STW是FullGC的STW。

3.3.4 survivor

当Eden区触发了垃圾回收,一部分对象被回收,一部分对象幸存下来,幸存下来的对象就开始向survivor区整理,首先是放到s0(From)区域,如果s0区域满了,则再次进行回收,和前面一样,有一部分对象幸存了下来,幸存的对象向s1整理,这是,S1中的对象已经整理好,而S0区已经空了,S1中的对象会全部放到S0区,这样循环往复,每一次循环对象的年龄+1,知道对象的年龄到达15(年龄字段放在对象头中,占4个bit,所以是15),把对象转移到老年代。

3.3.5 老年代

当老年代也放满了就会触发FullGC算法。FullGC执行时间大概是youngGC时间的10倍。随着时间推移,老年代进行一次FullGC所有的对象都存活了下来,就说明里面的对象全部都是有用的,也就是说通过垃圾回收也没有办法解决老年代内存已满的问题,这时就会内存溢出 (OOM Out Of Memory Error),程序结束。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值