62.Java中几种不同的引用-强软弱虚

2024-05-29 16:38
文章标签 java 引用 几种 不同 62 软弱

本文主要是介绍62.Java中几种不同的引用-强软弱虚,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 1.`Java`中几种不同的引用-强软弱虚概述
    • 1.1 强引用
    • 1.2 软引用
    • 1.3 弱引用
    • 1.4 虚引用

1.Java中几种不同的引用-强软弱虚概述

  1. java中的引用分为4种,强引用、软引用、弱引用、虚引用,引用强度依次逐渐减弱,都继承自Reference
    在这里插入图片描述
  2. 四种引用概述
    强引用:最传统的引用的定义,在开发中99%都是使用的强引用。即类似“Object obj = new Object()”这种引用关系。无论任何情况下,只要强引用的关系存在,垃圾收集器就永远不会回收掉被引用的对象。
    软引用:在系统将要发生内存溢出之前,将会把这些被软引用的对象列入回收范围之中进行回收。如果这次回收之后还没有足够的内存,才会抛出内存溢出异常。概括为:内存不足即回收。
    弱引用:当垃圾收集的时候,无论内存空间是否足够,被弱引用关联的对象就会被回收掉。概括为:发现即回收。
    虚引用:虚引用不会影响对象生存的时间。使用虚引用的目的是为了能在对象被垃圾回收器回收时收到一个系统通知。概括为:对象回收跟踪。
    在这里插入图片描述

1.1 强引用

在这里插入图片描述
强引用特点:
在这里插入图片描述

1.2 软引用

当内存足够时不会回收软引用对象,当内存不足时,才会回收软引用对象。
在这里插入图片描述
软引用使用:使用java.lang.ref.SoftReference类来实现软引用。
在这里插入图片描述
例子:

public class SoftReferenceTest {public static class User {public User(int id, String name) {this.id = id;this.name = name;}public int id;public String name;@Overridepublic String toString() {return "[id=" + id + ", name=" + name + "] ";}}public static void main(String[] args) {//创建对象,建立软引用
//        SoftReference<User> userSoftRef = new SoftReference<User>(new User(1, "songhk"));//上面的一行代码,等价于如下的三行代码User u1 = new User(1,"songhk");SoftReference<User> userSoftRef = new SoftReference<User>(u1);u1 = null;//取消强引用//从软引用中重新获得强引用对象System.out.println(userSoftRef.get()); // 拿到创建的User对象System.gc();System.out.println("After GC:");
//        //垃圾回收之后获得软引用中的对象System.out.println(userSoftRef.get());//如果堆空间内存足够,则不会回收软引用的可达对象。否则,会回收这个对象,输出null。
//try {//让系统认为内存资源紧张、不够
//            byte[] b = new byte[1024 * 1024 * 7];byte[] b = new byte[1024 * 7168 - 635 * 1024];} catch (Throwable e) {e.printStackTrace();} finally {//再次从软引用中获取数据System.out.println(userSoftRef.get());//在报OOM之前,垃圾回收器会回收软引用的可达对象。}}
}

1.3 弱引用

只被弱引用关联的对象在垃圾回收的时候就会被回收。
软引用、弱引用非常适合来保存那些可有可无的缓存数据。当内存足够的时候,这些缓存数据可以存着很长的时间;当内存不足的时候,这些缓存数据就可以被回收,不会导致内存溢出。
在这里插入图片描述
使用方法:
在这里插入图片描述
软引用与弱引用的不同:当进行GC的时候,需要通过算法来检查是否回收软引用对象(判断内存是否足够),而对于弱引用对象,GC总是进行回收。

例子:

public class WeakReferenceTest {public static class User {public User(int id, String name) {this.id = id;this.name = name;}public int id;public String name;@Overridepublic String toString() {return "[id=" + id + ", name=" + name + "] ";}}public static void main(String[] args) {//构造了弱引用WeakReference<User> userWeakRef = new WeakReference<User>(new User(1, "songhk"));//从弱引用中重新获取对象System.out.println(userWeakRef.get());System.gc();// 不管当前内存空间足够与否,都会回收它的内存System.out.println("After GC:");//重新尝试从弱引用中获取对象System.out.println(userWeakRef.get());}
}

1.4 虚引用

一个对象是否存在虚引用,完全不会影响对象的生命周期。为一个对象设置虚引用关联的唯一目的就是跟踪垃圾回收过程。比如,在这个对象被回收的时候,收到一个系统通知。
在这里插入图片描述
虚引用必须与引用队列一起使用。当垃圾回收器回收一个对象时,如果发现它还有虚引用,就会在回收对象之后,将虚引用加入到引用队列中,以通知应用程序对象的回收情况。
在这里插入图片描述
例子:

public class PhantomReferenceTest {public static PhantomReferenceTest obj;//当前类对象的声明static ReferenceQueue<PhantomReferenceTest> phantomQueue = null;//引用队列public static class CheckRefQueue extends Thread {@Overridepublic void run() {while (true) {if (phantomQueue != null) {PhantomReference<PhantomReferenceTest> objt = null;try {objt = (PhantomReference<PhantomReferenceTest>) phantomQueue.remove();} catch (InterruptedException e) {e.printStackTrace();}if (objt != null) {System.out.println("追踪垃圾回收过程:PhantomReferenceTest实例被GC了");}}}}}@Overrideprotected void finalize() throws Throwable { //finalize()方法只能被调用一次!super.finalize();System.out.println("调用当前类的finalize()方法");obj = this;}public static void main(String[] args) {Thread t = new CheckRefQueue();t.setDaemon(true);//设置为守护线程:当程序中没有非守护线程时,守护线程也就执行结束。t.start();phantomQueue = new ReferenceQueue<PhantomReferenceTest>();obj = new PhantomReferenceTest();//构造了 PhantomReferenceTest 对象的虚引用,并指定了引用队列PhantomReference<PhantomReferenceTest> phantomRef = new PhantomReference<PhantomReferenceTest>(obj, phantomQueue);try {//不可获取虚引用中的对象System.out.println(phantomRef.get());//将强引用去除obj = null;//第一次进行GC,由于对象可复活,GC无法回收该对象System.gc();Thread.sleep(1000);if (obj == null) {System.out.println("obj 是 null");} else {System.out.println("obj 可用");}System.out.println("第 2 次 gc");obj = null;System.gc(); //一旦将obj对象回收,就会将此虚引用存放到引用队列中。Thread.sleep(1000);if (obj == null) {System.out.println("obj 是 null");} else {System.out.println("obj 可用");}} catch (InterruptedException e) {e.printStackTrace();}}
}

更多JVM文章请访问我的JVM专栏:
https://blog.csdn.net/u011069294/category_10113093.html

这篇关于62.Java中几种不同的引用-强软弱虚的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1014068

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

2. c#从不同cs的文件调用函数

1.文件目录如下: 2. Program.cs文件的主函数如下 using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using System.Windows.Forms;namespace datasAnalysis{internal static

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听