java内存学习笔记

JVM内存

在这里插入图片描述
jvm将自己拿到的内存分成五个部分:栈,堆,程序计数器,本地方法站,方法区。

  • 本地方法栈: C++的native方法运行时候的栈
  • 栈: 函数运行过程中的临时变量,栈存储的对象实际是引用类型,存储的是一个地址,最终是指向堆区。
  • 堆:主要存对象。
  • 程序计数器:指向程序当前运行的位置
  • 方法区:存取一些元数据,JDK7之前叫做永久带,JDK8之后改名为元数据空间,主要存储一些静态方法或变量(static), 类加载器(class loader)

栈+本地方法栈+程序计数器= 线程私有,每个线程会单独创建这样一份内存 。

堆和方法区是全局共享。

程序运行结束之后,会将创建的栈空间 整个删除。

堆和栈

值创建过程

如上图,首先main线程创建一个栈,保存A,之后func1函数会创建新的栈,运行结束,删除栈。

在这里插入图片描述

对象创建过程:
只看fun1函数,首先为变量a,b栈上申请空间,new一个对象会发生,在堆上申请一块内存,包含两个部分,一个是地址,一个是内容,默认id = 0, name = null. 堆保存一个地址指向栈中的地址。下一行id 进行赋值,下一行name 进行赋值发现String也是一个对象,在堆中 新申请一块内存,保存char数组的值内存地址,person对象中name地段保存String的地址。

运行完毕之后,栈空间删除,但是堆上的空间怎么处理呢?

GC机制,垃圾回收。

方法区

保存static 变量或者方法, 全局。

GC

如何判断对象是否需要被清楚

GCroot

  • 被栈引用或者间接引用;

  • 或者被本地方法栈引用或间接引用的对象;

  • 或者被方法区直接或者间接引用的这些对象;

这些对象是不可以被删除。

清理堆区对象的思路

  1. 标记需要删除的对象—标记清理

缺点:产生内存碎片

  1. 标记整理 – 删除之后整理,比如删掉第一个后面的往前顶。

缺点:代价开销大

  1. 复制算法

将整个内存一分为二, 将对象创建在一区,然后需要删除的时候标记删除对象,之后不是直接删除,而是向二区复制不需要删除的对象。

缺点:需要两倍的内存。

实际的做法

划分堆- 年轻代(young), 老年代(0ld)

young再次划分三块:E, S, S (为表区分,S0, S1)

new对象出生在E区,E区快满之后,触发GC,也叫作young GC, 使用复制算法,复制到S0区。

对象朝生夕死,产生的比较大,但是幸存下来比较小,所以E区较大,S区较小。

为什么需要两个S区,

这两个S区交替工作,比如E幸存到S0区,删除E区和S1区,下一次E区快慢之后,标记S0和E区,将所有的幸存者保存到S1区,清空另外两个区。如此反复。

OLD区: 每一次youngGC,年龄就会加一,如果每一次Young GC都活下来了,如果满6岁,不在向S中复制,直接放在OLD区中维护,省的每次都在young区复制。

OLD保存六岁以上的对象还有一些大对象

大对象的消耗比较大,比如一个100000000大小的int数组。

OLD的内存快满也会触发GC, 每次OLD GC一般也会引起young GC,这也叫full GC, 引起Stop the world, java程序直接暂停,全力进行垃圾回收, 主要使用 标记清理或者标记整理算法。

垃圾收集器:ParNew, CMS, G1,其中G1有全新的理念。

指针压缩

对象的组成:对象的头和body

头也分成三个部分:

  • mark world(8B) ,记录对象信息,是否锁住,GC年龄等

  • Klass world(4B), 指向C++中对象的地址,Klass指针指向metaspace区的对象, Klass对象记录对象的元数据信息。

  • Array length(4B),对象不是数组类型不存在这个字段
    在这里插入图片描述

栈中保存值类型,也保存对象引用,如果指针压缩就是4字节,没有压缩就是8字节.

为什么对象的指针可以是4字节

因为java对象是8字节对齐,每个地址住8个字节而不是1个字节,所以4字节,可以表示2^32 * 8 Byte= 32GB的内存地址。

堆内存在32G以内都是默认开启指针压缩,每个对象的地址用4字节宝石,但是堆超过32G无法压缩每个对象地址必须要用8字节。

可能33G, 34G堆大小中申请的对象的个数反而没有32位中申请的多。

地址变大了,变成8个字节了。

普通对象指针压缩技术: 四字节地址可以对32G内存寻址。

klass C++对象并不是普通对象,为什么也可以压缩实现呢?

在元空间中,开启压缩后,KLASS部分位于压缩累空间上,包括ITABLE, VTABLE,压缩类空间是连续的4GB的空间,这里的32bit确实是表示4GB的空间。

避免创建巨大的动态代理链,会占用metaspace,撑爆压缩累空间,程序报错。

metaSpace开启指针压缩之后,分成两个部分:

  • 压缩类空间:一些KLASS, itable等较小的数据

  • non-Class: 除上面之间的元数据信息;

在这里插入图片描述


原视频连接
视频连接2

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值