小仙女讲JVM(3)—垃圾收集机制

2024-03-11 03:59

本文主要是介绍小仙女讲JVM(3)—垃圾收集机制,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在上一篇中我们说过,自动内存管理分为两部分:给对象分配内存和回收分配给对象的内存。这篇我们说说后者,即回收分配给对象的内存。回收内存要用到垃圾收集机制,英文名儿是GC(Garbage Collection)。
在这里插入图片描述

在本部分我们要解决如下几个问题:

  1. 哪些内存需要回收?
  2. 什么时候回收?
  3. 如何回收?
哪些内存需要回收?

堆和方法区的内存需要回收,其余的不需要回收。
因为只有堆和方法区是线程共享的,其余的是与线程“同生共死”的,线程结束,内存自然就跟着回收了,所以不用管它们。

什么时候回收?

(1)在堆里面:

当对象“死了”的时候就要对其进行内存回收了。啥叫对象死了?就是没有地方引用它了,它无用了。那怎么判断它是否死了呢?有两种方法。

  • 引用计数算法

给对象添加一个引用计数器,每当有一个地方引用它时,计数器的值就+1,当引用失效时,计数器的值就-1,当计数器的值为0时,代表此对象已不被引用,也就是“可以死了”。
但这有一个弊端,就是循环引用的问题。就像下图,堆里的两个对象即使无用了也没办法对其进行回收,因为它们互相引用着,计数器的值至少为1。
在这里插入图片描述

  • 可达性分析

所有生成的对象都是一个称为“GC Roots”的根的子树。从GC Roots开始向下搜索,搜索所经过的路径称为引用链。当一个对象到GC Roots没有任何引用链可以到达时,就称这个对象是不可达的,也就是可以被GC回收了。这个是Java中采用较多的方式。
就像下图中的堆中未被引用的对象,就可以对其进行回收。
在这里插入图片描述
看到此,本仙女就要提问了:怎么判断一个对象是否还存在着引用?java中的引用分为4种:

  • 强引用:Object o=new Object(),只要强引用存在,GC永远不会回收掉被引用的对象。
  • 软引用:描述一些还有用但非必需的对象。当系统即将发生内存溢出了,就会对其进行回收。
  • 弱引用:只要进行GC,就会对其进行回收。
  • 虚引用:这是最弱的一种引用关系,无法通过虚引用来取得一个对象实例。它的作用是:能在这个对象被收集器回收时收到一个系统通知。

(2)在方法区里面:

我们知道,方法区里存储的是已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。所以我们在方法区里面进行垃圾回收,回收的是一些废弃的常量和无用的类。

  • 怎么判断一个常量是否被废弃了?

看引用计数就可以,如果没有对象引用该常量,则说明此常量被废弃了,也就可以回收了。

  • 怎么判断一个类是无用的类?

有3种情况:
a、该类所有的实例都已经被回收。
b、加载该类的ClassLoader已经被回收。
c、该类对应的java.lang.Class对象没有任何地方被引用,无法在任何地方通过反射访问该类的方法。

如何回收?

有4种算法作为理论:
• 标记-清除算法
• 复制算法
• 标记-整理算法
• 分代收集算法

有5种收集器作为实现:

这一部分在以前博客中讲过,不再赘述啦:【JVM】初识JVM(下)

后记

内存溢出:系统无法再分配出你需要的空间。比如在堆中无法再给新生的对象分配内存了,在栈里栈满了无法再让新栈帧进栈了。

内存泄漏:内存被对象占用着不还,就叫内存泄露。

这篇关于小仙女讲JVM(3)—垃圾收集机制的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

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

JS常用组件收集

收集了一些平时遇到的前端比较优秀的组件,方便以后开发的时候查找!!! 函数工具: Lodash 页面固定: stickUp、jQuery.Pin 轮播: unslider、swiper 开关: switch 复选框: icheck 气泡: grumble 隐藏元素: Headroom

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

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

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