


指针碰撞,就是一边是用过的,一边是空闲的,中间有个指针,然后挪动指针去分配内存
空闲列表是内存是乱七八糟的,那就要记录那些内存卡是可用的


cas就是比较交换
tlab就是搞个 threadlocal 每个线程去拿他自己持有的内存块
也就是说 在我们的那个堆里面,给我们某具体的线程,分配一块自己独立的空间,我这个线程内部的所有对象都往上面放,这一块空间不可能特别大吧,注意,是有一个参数可以设置它,叫TLAB_SIZE去设置,它默认你不设置的话,好像是伊甸园区的1%吧
如果放不下就走cas放到eden区




我比方说我去,我去,我们上节课给大家去讲过嘛,讲过一个,比方说我,我通过这一个对象,干嘛要去找到这 compute 方法,在元数据区里面那些个代码,怎么去找?
实际上就是通过什么东西啊?
通过这个东西,通过这一个类型指针去找的。

这个代码指的是图片这里的

就是我们整个类的这些个乱七八糟的这些代码
它是放在我们方法区的
我们类装载完之后,JVM内部给我们Java开发人员,我们如果想要访问这个类的一些信息,我们可以通过这一个类,通过这一个类对象,去访问。

在堆区的class是给我们java人员用的
方法区的class存储介质是c++的对象
堆区class不存代码,是存个入口,可以理解为镜像
代码信息在方法区



可以看到Object header就是对象头
还有alignment是用来对齐的




指针压缩




每个线程都有自己的栈空间


test2的作用域 是没有逃逸出这个方法
有个参数可以开启逃逸分析 jdk7后的版本都是默认开启的
如果关闭 对象直接分配在堆上
-XX代表不稳定的参数
栈帧比较小 有可能分配不下这个对象 剩余的空间总大小可以放下 但是没有一整块能放下这个对象
通过标量替换 他可以把一些成员属性 放到零散的内存中 也有参数可以开启 jdk7默认是开启的


运行这个方法一亿次,会分配一亿个对象。
这些对象若分配在堆上,会产生大量 GC。因为方法结束后,这些对象会失去 GC Root 的引用,下一次 GC 时会被回收。
这些对象若分配在栈上,几乎不会发生 GC------ 仅排除其他特殊情况导致 GC 的可能,整体无明显 GC 行为。
对象通常会分配到堆上,且多数情况下会先放入伊甸园区。
此前提到过一个概念:若对象体积较大,或栈内分配失败时,会触发不同的分配规则。
关于大对象的定义后续会具体讲解,大对象会直接被分配到老年代(Old区);若对象体积未达到大对象标准,则会先尝试TLAB分配。
正如之前所说,线程会在伊甸园区为当前线程划分一小块专属内存空间(即TLAB),对象会优先分配到该线程对应的TLAB中------TLAB本质上仍是伊甸园区内的内存空间。
若TLAB分配成功,对象分配流程完成;若TLAB分配失败,则直接在伊甸园区通过CAS机制分配对象。
接下来具体讲解对象分配的相关规则。
总结
- 对象默认分配至堆的伊甸园区,大对象会直接进入老年代;
- 非大对象优先尝试线程专属的TLAB分配(TLAB位于伊甸园区);
- TLAB分配失败时,会通过CAS机制直接在伊甸园区分配对象。

栈帧默认是1M,eden也有五六十兆被占用 这是jvm占用的

eden已经满了 再放一个到eden区,就会触发minor gc
会把存活的对象挪到survivor区





大对象内存分配优化:
提前进入老年代:若系统中有大量大对象且不会被垃圾回收,可设置大对象提早进入老年代,释放年轻代空间,提升性能。
避免内存占用:若大对象不提早进入老年代,会在内存中频繁复制移动,占用内存空间,影响其他对象分配。
eden放不下 有参数可以控制大对象的大小

直接进老年代

"16MB" 实际是 G1 GC 的 Heap Region(堆区域)单元大小 ------G1 会将堆划分为多个等大的 Region,当堆总大小处于 8GB~16GB 区间时,Region 默认大小为 16MB,Eden 区由多个这样的 16MB Region 组成

这种情况为什么要设置一个大对象提早进入老年段,如果你知道你系统里面大量的对象都比较大,
,而且这些对象又是不会被垃圾收集的,那我就可以设置这样大对象,让它提早进入老年段,对不对?
长期存活对象分代年龄设置: 默认分代年龄:一般情况下,对象分代年龄达到 15 岁会挪到老年代,可通过 "Max Tenuring
Threshold" 参数指定。 优化设置依据:若能估算对象生命周期不长,多次 GC 后会被回收,可将分代年龄设置小一些,如设置为 8 或5,节约年轻代空间。




对象动态年龄判断机制: 机制定义:做完 minor GC 后,若一批对象放到年轻代(包括 Survivor 区),其大小超过
Survivor 区的 50%,会将等于及大于该年龄的对象挪到老年代。 案例影响:在电商网站案例中,每 14 秒产生的 60 兆对象因超过
Survivor 区 50%,会挪到老年代,导致老年代很快放满触发 Full GC。
JVM 参数设置方法: 避免随意设置:系统上线前进行发布测试,应根据系统要承载的压力推算 JVM 参数设置,而非随意设置。
依据业务估算:以电商网站为例,可根据订单量、对象大小、业务复杂度等估算每秒往堆中分配的对象大小,进而设置堆、元空间、栈等的大小。
比例设置说明:年轻代中伊甸园区和 Survivor 区默认比例为 8:1:1,但需开启特定参数,且实际比例可能有误差,是否开启要根据业务情况决定。
这里的例子 eden满了,会直接进入old,因为60M超过了S区的50%
old 五六分钟就放满了 触发full gc
不能这么频繁full gc 要做优化 几乎不发生full gc
频繁触发负 GC 问题:当前系统中每五六分钟区域放满触发负
GC,而正常情况应是半小时、几小时甚至几天几周做一次,大促时虽会频繁些,但因垃圾对象导致频繁负 GC 不合适,可对 JVM
参数模型进行优化。 根本原因:对象动态年龄判断机制导致频繁负 GC。

都是朝生夕死的对象 把年轻代放大一点

那就25秒那个对象会被放到s1区,然后其他对象都会被回收
在上线前 要估算一个模型 然后放到测试环境测试一下 然后再去调整参数


老年代分配担保机制讲解: 机制流程:在年轻代做 minor GC 之前,JVM会判断老年代剩余可用空间。若年轻代剩余所有对象大于老年代剩余可用空间,若担保参数未配置则直接做 full GC;若配置了担保参数,会基于历次minor GC 挪到老年代对象的经验值判断,若老年代能放下,就不做 full GC,直接做 minor GC。
担保含义:担保年轻代对象挪到老年代后有可能不触发 full GC。 机制优势:使用该机制,在做 minor GC 之前判断若大概率会做
full GC,先做一次 full GC 再做 minor GC,可使这次 minor GC 时间短,且 full GC能有效回收很多对象,提高效率。






都是负数的 是被回收

没有被回收不会触发这个方法,回收的才会触发这个方法;回收前会触发该方法


这样增加引用 就能避免回收了~
但!!

这个没啥用 看看就好


full gc也会回收方法区的,比如类元信息,那要回收它,必须堆里面的对象都要没有了,那指针就没指向了,自然可以回收掉方法区的东西

