先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
正文
[
]( )
-
step1: 第一次扫描,通过GC root对象判断堆内存中哪些对象可以进行垃圾回收,进行标记。
-
step2: 第二次扫描, 将那些标记的GC root对象进行垃圾回收,只需要将起始内存地址与终止内存地址放入空闲内存区就行。
第一个依旧是标记,第二步会进行一个空间整理,从而不产生碎片。
优点:避免了内存碎片
缺点:对空间的整理使得效率比较低下。
特点:
将管理的内存分为2块区域,from区域与to区域,将那些不需要回收的对象从from区域拷贝到to区域。复制的过程中完成内存区域的整理。之后交换from和to的指向。
优点:不会产生内存碎片
缺点:需要双倍的内存空间,内存利用率不高,而且拷贝也需要时间。[
]( )
| 垃圾回收算法 | 优点 | 缺点 |
| — | — | — |
| 标记清除算法(Mark Sweep) | 速度较快 | 产生内存碎片 |
| 标记整理算法(Mark Compact) | 没有内存碎片 | 速度慢 |
| 复制算法(Copy) | 没有内存碎片 | 需要占用双倍内存空间 |
注意:实际的JVM垃圾回收算法中上面的三种算法是综合使用的。
========================================================================
Garden of Eden:伊甸园 garbage:垃圾
[
]( )
新生代主要由三部分内容组成,分别是Eden区,幸存区from,幸存区to。 通常情况下只有Eden区与幸存区from会存放数目,幸存区to只有垃圾回收时,复制对象会用到。堆内存的新生代进行一次垃圾回收(Minor GC),大部分对象都会都会被回收。
老年代通常存放一些经常被使用的对象,一个对象如果经历多次垃圾回收仍然幸存,那么该对象会从新生代放入老年代。只有新生代内存不足并且老年代内存也不足的时候才会触发full GC对老年代的对象进行垃圾回收。
为什么需要进行划分?
实际环境中,对象的生命周期是不同的,老年代的对象生命周期比较长,可能很长时间才进行一次垃圾回收。新生代的对象生命周期比较短,垃圾回收比较频繁。这种分区法方便采用不同的垃圾回收算法更加有效的进行垃圾回收。
step1:程序刚刚开始运行,产生的对象先放入Eden区,当Eden区放不下的时候。
step2:对Eden区进行Minor GC,并将没有被垃圾回收的对象复制的幸存区To,然后交换幸存区To和幸存区From,第一次垃圾回收的最终的效果如下图所示:
step3: 第一次Minor GC, Eden区又有空间可以分配给新的对象使用,经过一段时间Eden又不够用了,触发第二次Minor GC, 这次垃圾会检查Eden区以及幸存区From哪些对象可以存活,并将这些对象复制到幸存区To,然后交换幸存区To和幸存区From,这个时候Eden区又空了出来,可以放置新的对象。
实际垃圾回收过程中,JVM会对每个对象经过垃圾回收幸存下来的次数进行记录,比如上图中,幸存区的2个对象经过垃圾回收的次数分别是1和2。
step4: 当一些对象经过垃圾回收的次数仍然幸存的次数达到一个阈值(说明这个对象价值比较高),那么这个对象会被移动到老年代。
极端情况考虑:Eden区,from区,老年区都已经满了?
此时会触发Full GC(优先Minor GC,Minor GC依旧内存不够)
对象首先分配在伊甸园区域
- 新生代空间不足时,触发
minor gc
,伊甸园和from
存活的对象使用copy
复制到 to 中,存活的
对象年龄加 1并且交换from to
minor gc
会引发stop the world
,暂停其它用户的线程,等垃圾回收结束,用户线程才恢复运行
暂停时间较短,由于新生代大部分对象都是垃圾,复制的对象很少,所以效率较高
-
当对象寿命超过阈值时,会晋升至老年代,最大寿命是15(4bit,对象头存储)
-
当老年代空间不足,会先尝试触发
minor gc
,如果之后空间仍不足,那么触发full gc,STW
的时
间更长
Full GC
的stop the world
的时间要比MInor GC
时间长,老年代存活对象较多加上空间整理时间,所以停止时间会较长。
如果Full GC
后,空间仍然不足会触发内存不足的异常。
| 参数含义 | 参数 | 备注 |
| — | — | — |
| 堆初始大小 | -Xms | |
| 堆最大大小 | -Xmx 或 -XX:MaxHeapSize=size | |
| 新生代大小 | -Xmn 或 (-XX:NewSize=size + -XX:MaxNewSize=size ) | NewSize是初始大小,MaxNewSize是最大大小。 |
| 幸存区比例(动态) | -XX:InitialSurvivorRatio=ratio 和 -XX:+UseAdaptiveSizePolicy | 幸存区的比例,默认是8,假设新生代10M内存,8M划分给Eden区,剩下的二等分,一份from,一份to。 |
| 幸存区比例 | -XX:SurvivorRatio=ratio | 动态调整幸存区比例 |
| 晋升阈值 | -XX:MaxTenuringThreshold=threshold | 用于动态调整幸存区比例 |
| 晋升详情 | -XX:+PrintTenuringDistribution | 用于动态调整幸存区比例 |
| GC详情 | -XX:+PrintGCDetails -verbose:gc | 打印详情信息 |
| FullGC 前 MinorGC | -XX:+ScavengeBeforeFullGC | 默认在Full GC 前进行一次Minor GC |
情况1:什么都不放的情况
new generation:新生代 tenured generation:老年代
package cn.itcast.jvm.t2;
import java.util.ArrayList;
/**
- 演示内存的分配策略
*/
public class Demo2_1 {
private static final int _512KB = 512 * 1024;
private static final int _1MB = 1024 * 1024;
private static final int _6MB = 6 * 1024 * 1024;
private static final int _7MB = 7 * 1024 * 1024;
private static final int _8MB = 8 * 1024 * 1024;
//加入Java开发交流君样:756584822一起吹水聊天
// -Xms20M -Xmx20M -Xmn10M : 堆初始与最大大小都是20M,新生代的大小为10M.
// -XX:+UseSerialGC : 为了学习方便,采用这个垃圾回收器,默认的垃圾回收器并不是这个。
// -XX:+PrintGCDetails -verbose:gc :打印详细信息
// -XX:-ScavengeBeforeFullGC :在Full GC 前进行 Minor GC.
public static void main(String[] args) throws InterruptedException {
new Thread(() -> {
ArrayList<byte[]> list = new ArrayList<>();
list.add(new byte[_8MB]);
list.add(new byte[_8MB]);
}).start();
System.out.println(“sleep…”);
Thread.sleep(1000L);
}
}
情况1执行结果
可以看到即使用户没有创建对象,系统对象也要占据一部分堆内存空间。
Heap
def new generation total 9216K, used 2341K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
// 新生代的空间总的大小为9216K,这里没有把To空间给计算进去,系统任务To的空间是分配是不可用的,所以不是10M,已经使用了2341K,[]内部则是内存地址范围。
eden space 8192K, 28% used [0x00000000fec00000, 0x00000000fee49420, 0x00000000ff400000)
//
from space 1024K, 0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff500000)
to space 1024K, 0% used [0x00000000ff500000, 0x00000000ff500000, 0x00000000ff600000)
tenured generation total 10240K, used 0K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
// 老年代大小为10M,可以看到没有任何空间使用
//加入Java开发交流君样:756584822一起吹水聊天
the space 10240K, 0% used [0x00000000ff600000, 0x00000000ff600000, 0x00000000ff600200, 0x0000000100000000)
Metaspace used 3394K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 378K, capacity 388K, committed 512K, reserved 1048576K
Java的内存对象都是分配在堆上吗
情况2:新生代堆空间放满,触发GC
public static void main(String[] args) throws InterruptedException {
ArrayList<byte[]> list = new ArrayList<>();
list.add(new byte[_7MB]); // 系统类占用2341K,加上new的7MB触发垃圾回收
}
情况2执行结果
[GC (Allocation Failure) [DefNew: 2342K->696K(9216K), 0.0029193 secs] 2342K->696K(19456K), 0.0029867 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
// GC:minor GC(新生代垃圾回收) FUll GC (老年代垃圾回收)
// [Times: user=0.00 sys=0.00, real=0.00 secs] 垃圾回收执行时间
Heap
def new generation total 9216K, used 8110K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
eden space 8192K, 90% used [0x00000000fec00000, 0x00000000ff33d8c0, 0x00000000ff400000)
from space 1024K, 67% used [0x00000000ff500000, 0x00000000ff5ae100, 0x00000000ff600000)
to space 1024K, 0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff500000)
tenured generation total 10240K, used 0K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
the space 10240K, 0% used [0x00000000ff600000, 0x00000000ff600000, 0x00000000ff600200, 0x0000000100000000)
Metaspace used 3539K, capacity 4536K, committed 4864K, reserved 1056768K
//加入Java开发交流君样:756584822一起吹水聊天
class space used 395K, capacity 428K, committed 512K, reserved 1048576K
情况三: 新生代内存随着对象的增多放不下了
public static void main(String[] args) throws InterruptedException {
ArrayList<byte[]> list = new ArrayList<>();
list.add(new byte[_7MB]);
list.add(new byte[_512KB]);
list.add(new byte[_512KB]);
}
执行结果
新生代放不下,将新生代的对象放置到老年代。
[GC (Allocation Failure) [DefNew: 2342K->670K(9216K), 0.0022591 secs] 2342K->670K(19456K), 0.0023131 secs] [Times: user=0.02 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [DefNew: 8678K->538K(9216K), 0.0061246 secs] 8678K->8354K(19456K), 0.0061637 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
Heap
def new generation total 9216K, used 1132K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
eden space 8192K, 7% used [0x00000000fec00000, 0x00000000fec94930, 0x00000000ff400000)
from space 1024K, 52% used [0x00000000ff400000, 0x00000000ff486a00, 0x00000000ff500000)
to space 1024K, 0% used [0x00000000ff500000, 0x00000000ff500000, 0x00000000ff600000)
tenured generation total 10240K, used 7815K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
the space 10240K, 76% used [0x00000000ff600000, 0x00000000ffda1f80, 0x00000000ffda2000, 0x0000000100000000)
Metaspace used 3539K, capacity 4536K, committed 4864K, reserved 1056768K
//加入Java开发交流君样:756584822一起吹水聊天
class space used 395K, capacity 428K, committed 512K, reserveed 1048576K
情况四:一开始直接分配大于新生代的内存,如果老年代放的下,则直接放到老年代
public static void main(String[] args) throws InterruptedException {
ArrayList<byte[]> list = new ArrayList<>();
list.add(new byte[_8MB]);
}
执行结果
Heap
//加入Java开发交流君样:756584822一起吹水聊天
def new generation total 9216K, used 2507K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
eden space 8192K, 30% used [0x00000000fec00000, 0x00000000fee72ca8, 0x00000000ff400000)
from space 1024K, 0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff500000)
最后
针对最近很多人都在面试,我这边也整理了相当多的面试专题资料,也有其他大厂的面经。希望可以帮助到大家。
下面的面试题答案都整理成文档笔记。也还整理了一些面试资料&最新2021收集的一些大厂的面试真题(都整理成文档,小部分截图)
最新整理电子书
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
, 0x00000000ff400000, 0x00000000ff500000)
最后
针对最近很多人都在面试,我这边也整理了相当多的面试专题资料,也有其他大厂的面经。希望可以帮助到大家。
下面的面试题答案都整理成文档笔记。也还整理了一些面试资料&最新2021收集的一些大厂的面试真题(都整理成文档,小部分截图)
[外链图片转存中…(img-kK99fG7p-1713455974064)]
最新整理电子书
[外链图片转存中…(img-g2F677uR-1713455974064)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-3dHTruoT-1713455974065)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!