最全Java工程师必看指南的【4种引用】,圆我大厂梦

最后

既已说到spring cloud alibaba,那对于整个微服务架构,如果想要进一步地向上提升自己,到底应该掌握哪些核心技能呢?

就个人而言,对于整个微服务架构,像RPC、Dubbo、Spring Boot、Spring Cloud Alibaba、Docker、kubernetes、Spring Cloud Netflix、Service Mesh等这些都是最最核心的知识,架构师必经之路!下图,是自绘的微服务架构路线体系大纲,如果有还不知道自己该掌握些啥技术的朋友,可根据小编手绘的大纲进行一个参考。

image

如果觉得图片不够清晰,也可来找小编分享原件的xmind文档!

且除此份微服务体系大纲外,我也有整理与其每个专题核心知识点对应的最强学习笔记:

  • 出神入化——SpringCloudAlibaba.pdf

  • SpringCloud微服务架构笔记(一).pdf

  • SpringCloud微服务架构笔记(二).pdf

  • SpringCloud微服务架构笔记(三).pdf

  • SpringCloud微服务架构笔记(四).pdf

  • Dubbo框架RPC实现原理.pdf

  • Dubbo最新全面深度解读.pdf

  • Spring Boot学习教程.pdf

  • SpringBoo核心宝典.pdf

  • 第一本Docker书-完整版.pdf

  • 使用SpringCloud和Docker实战微服务.pdf

  • K8S(kubernetes)学习指南.pdf

image

另外,如果不知道从何下手开始学习呢,小编这边也有对每个微服务的核心知识点手绘了其对应的知识架构体系大纲,不过全是导出的xmind文件,全部的源文件也都在此!

image

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

这些引用的区别仅在于垃圾回收器管理它们的方式。如果你从未听说过它们,这意味着你只使用强大的。了解差异可以帮助您,特别是如果您需要存储临时对象并且无法使用真正的缓存库(如eHcache或Guava)。

由于这些类型与 JVM 垃圾回收器密切相关,因此我将简要回顾一下有关 JAVA 中垃圾回收的一些信息,然后介绍不同的类型。

文章目录

    • 介绍

    • 垃圾回收器

    • 问题

    • 强引用

    • 软引用

    • 弱引用

    • 幻像引用

    • 结论

垃圾回收器


Java和C++之间的主要区别在于内存管理。在Java中,开发人员不需要知道内存是如何工作的(但他应该知道!),因为JVM通过其垃圾回收器来处理这一部分。

创建对象时,它由 JVM 在其中分配。堆是内存中的有限空间量。因此,JVM 通常需要删除对象才能释放空间。要销毁对象,JVM 需要知道此对象是处于活动状态还是非活动状态。如果对象被垃圾回收root引用(传递),则该对象仍在使用中。

例如:

  • 如果对象 C 由对象 B 引用,B 由对象 A 引用,A 由_垃圾回收root_引用,则 C、B 和 A 被视为活动(情况 1)。

  • 但是,如果 A 不再引用 B,则 C 和 B 不再处于活动状态,可以销毁(案例 2)。

JVM

由于这篇文章不是关于垃圾收集器的,我不会在解释中深入介绍,但仅供参考,有4种类型的垃圾收集root:

  1. 局部变量

  2. 活动 Java 线程

  3. 静态变量

  4. JNI 引用,这些 Java 对象包含本机代码,而不是由 jvm 管理的内存

Oracle 没有指定如何管理内存,因此每个 JVM 实现都有自己的一组算法。但这个想法总是一样的:

- JVM使用一种递归算法来查找非活动对象并标记它们

- 标记的对象被最终确定(调用finize()方法)然后销毁

- JVM有时会移动剩余对象的一部分,以便在堆中重建大面积的自由连续空间

问题


如果JVM管理内存,你为什么需要关心?因为这并不意味着你不能有内存泄漏

大多数情况下,您在没有意识到的情况下使用垃圾回收根目录。例如,假设您需要在程序的生命周期内存储一些 objet(因为它们的初始化成本很高)。您可能会使用静态整理(List、Map 等)来存储和检索代码中任何位置的这些对象:


public static Map<K, V> myStoredObjects= new HashMap<>();



但是,通过这样做,可以防止 JVM 破坏集合中的对象。通过错误,你可能会和一个超出记忆的错误。例如:


public class OOM {

    public static List<Integer> myCachedObjects = new ArrayList<>();

 

    public static void main(String[] args) {

        for (int i = 0; i < 100_000_000; i++) {

            myCachedObjects.add(i);

        }

    }

}



输出为:

线程“main” java.lang.OutOfMemoryError中的异常:Java heap space

Java提供了不同类型的引用来避免OutOfMemoryError。

某些类型允许 JVM 释放对象,即使程序仍然需要这些对象。开发人员有责任处理这些情况。

强引用


强参考是标准参考。当你在对象 obj 上创建这样的内容时:


MyClass obj = new MyClass ();



您正在创建一个名为“obj”的强引用,该引用指向新创建的 MyClass 实例。当垃圾回收器查找非活动对象时,它只检查 objets 是否强可访问,这意味着通过强引用传递链接到垃圾回收根。

使用此类型的引用会强制 JVM 将对象保留在堆中,直到未按照“垃圾回收器”一节中所述使用对象为止。

软引用


根据java API的软参考有:

“软引用对象,由垃圾回收器自行决定清除,以响应内存需求”

这意味着,如果您在不同的JVM上运行程序,软引用的行为可能会改变(Oracle的Hotspot,Oracle的JRockit,IBM的J9等)。

让我们来看看Oracle的JVM Hotspot(标准和最常用的JVM),看看它如何管理软引用。根据甲骨文文档:

“默认值为每兆字节 1000 毫秒,这意味着对于堆中每 MB 的可用空间,软引用将存活 1 秒(在收集了对对象的最后一个强引用之后)”

下面是一个具体示例:让我们假设堆是 512 MB,有 400MB 可用。

我们创建一个对象 A,软引用对象缓存,强引用 A 到对象 B。由于 A 强烈引用 B,因此它非常可访问,并且不会被垃圾回收器删除(情况 1)。

想象一下,现在 B 已被删除,因此 A 仅被软引用到缓存对象。如果对象 A 在接下来的 400 秒内未被强烈引用,则会在超时后将其删除(情况 2)。

soft_ref1

以下是操作软引用的方法:


public class ExampleSoftRef {

    public static class A{

 

    }

    public static class B{

        private A strongRef;

 

        public void setStrongRef(A ref) {

            this.strongRef = ref;

        }

    }

    public static SoftReference<A> cache;

 

    public static void main(String[] args) throws InterruptedException{

        //用软instanceA的引用的缓存的初始化

        ExampleSoftRef.A instanceA = new ExampleSoftRef.A();

        cache = new SoftReference<ExampleSoftRef.A>(instanceA);

        instanceA=null;

        // 现在instanceA是只软可到达的且可以在一段时间后,由垃圾回收器删除

        Thread.sleep(5000);

 

        ...

        ExampleSoftRef.B instanceB = new ExampleSoftRef.B();

        //从缓存具有软引用的实例后,我们不能肯定instanceA仍然存在

        //如果需要,我们需要检查并重新创建instanceA

        instanceA=cache.get();

        if (instanceA ==null){

            instanceA = new ExampleSoftRef.A();

            cache = new SoftReference<ExampleSoftRef.A>(instanceA);

        }

        instanceB.setStrongRef(instanceA);

        instanceA=null;

        // instanceA现在只是轻轻地由缓存引用和强烈引用,所以它不能是clea

 

        ...

    }

}



但是,即使垃圾回收器自动删除了软引用对象,软引用(也是对象)**也不会被删除!**因此,您仍然需要清除它们。例如,对于像 64 MB (Xmx64m) 这样的低堆大小,下面的代码给出了一个 OutOfMemoryException,尽管使用了软引用。


public class TestSoftReference1 {

 

    public static class MyBigObject{

        //each instance has 128 bytes of data

        int[] data = new int[128];

    }

    public static int CACHE_INITIAL_CAPACITY = 1_000_000;

    public static Set<SoftReference<MyBigObject>> cache = new HashSet<>(CACHE_INITIAL_CAPACITY);

 

    public static void main(String[] args) {

        for (int i = 0; i < 1_000_000; i++) {

            MyBigObject obj = new MyBigObject();

            cache.add(new SoftReference<>(obj));

            if (i%200_000 == 0){

                System.out.println("size of cache:" + cache.size());

            }

        }

        System.out.println("End");

    }

}



输出代码为:

缓存大小:1

缓存大小:200001

缓存大小:400001

缓存大小:600001

线程“主”中的异常 java.lang.OutOfMemoryError: 超出 GC 开销限制

Oracle 提供了一个 ReferenceQueue,当引用的对象只能软访问时,该队列会填充软引用。使用此队列,您可以清除软引用并避免超出内存错误。

使用 ReferenceQueue,与上面相同的代码具有相同的堆大小(64 MB),但要存储的数据更多(500 万对 100 万),可以工作:


public class TestSoftReference2 {

    public static int removedSoftRefs = 0;


### 最后

一次偶然,从朋友那里得到一份“java高分面试指南”,里面涵盖了25个分类的面试题以及详细的解析:JavaOOP、Java集合/泛型、Java中的IO与NIO、Java反射、Java序列化、Java注解、多线程&并发、JVM、Mysql、Redis、Memcached、MongoDB、Spring、Spring Boot、Spring Cloud、RabbitMQ、Dubbo 、MyBatis 、ZooKeeper 、数据结构、算法、Elasticsearch 、Kafka 、微服务、Linux。

这不,马上就要到招聘季了,很多朋友又开始准备“金三银四”的春招啦,那我想这份“java高分面试指南”应该起到不小的作用,所以今天想给大家分享一下。

![image](https://img-blog.csdnimg.cn/img_convert/13eded2be5d05c779338c81c73419f3c.webp?x-oss-process=image/format,png)

> 请注意:关于这份“java高分面试指南”,每一个方向专题(25个)的题目这里几乎都会列举,在不看答案的情况下,大家可以自行测试一下水平 且由于篇幅原因,这边无法展示所有完整的答案解析

> **本文已被[CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】](https://bbs.youkuaiyun.com/forums/4f45ff00ff254613a03fab5e56a57acb)收录**

**[需要这份系统化的资料的朋友,可以点击这里获取](https://bbs.youkuaiyun.com/forums/4f45ff00ff254613a03fab5e56a57acb)**

服务、Linux。

这不,马上就要到招聘季了,很多朋友又开始准备“金三银四”的春招啦,那我想这份“java高分面试指南”应该起到不小的作用,所以今天想给大家分享一下。

[外链图片转存中...(img-16XLMhj4-1715569065610)]

> 请注意:关于这份“java高分面试指南”,每一个方向专题(25个)的题目这里几乎都会列举,在不看答案的情况下,大家可以自行测试一下水平 且由于篇幅原因,这边无法展示所有完整的答案解析

> **本文已被[CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】](https://bbs.youkuaiyun.com/forums/4f45ff00ff254613a03fab5e56a57acb)收录**

**[需要这份系统化的资料的朋友,可以点击这里获取](https://bbs.youkuaiyun.com/forums/4f45ff00ff254613a03fab5e56a57acb)**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值