JVM工作原理与实战(二十二):方法区的垃圾回收

简介: JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了Java的内存管理和自动垃圾回收、方法区的垃圾回收等内容。

一、Java的内存管理和自动垃圾回收

运行时数据区知识回顾

Java虚拟机(JVM)在运行Java程序期间,会创建并维护一系列内存区域,这些区域总称为运行时数据区。这些区域根据其用途和特性,被严格定义并管理。《Java虚拟机规范》详细规定了这些区域的作用和行为,以确保所有Java虚拟机实现的一致性和正确性。

线程不共享区域:

  • 程序计数器:用于存储当前线程执行的字节码指令地址。这个区域是每个线程独有的,不共享。
  • Java虚拟机栈:每个线程在创建时都会创建一个虚拟机栈,每个方法调用都会创建一个栈帧,用于存储局部变量、操作数栈、动态链接和方法出口信息。
  • 本地方法栈:与虚拟机栈相似,本地方法栈为native方法提供服务。

线程共享区域:

  • 方法区:用于存储已被JVM加载的类信息、常量、静态变量以及即时编译器编译后的代码等数据。
  • 堆:堆是所有线程共享的区域,用于动态分配内存。所有的对象实例以及数组都应当在堆上分配。

image.gif

在运行时数据区中,线程不共享的部分都是伴随着线程的创建而创建,随着线程的销毁而销毁。而方法的栈帧在执行完方法之后就会自动弹出栈并释放掉对应的内存。这种内存管理方式可以有效地减少内存的浪费,并且可以防止内存泄漏问题的发生。

image.gif

二、方法区的垃圾回收

1.回收条件

在Java中,方法区用于存储已被虚拟机加载的类信息、常量、静态变量以及即时编译器编译后的代码等数据。与堆区一样,方法区也有垃圾回收机制,主要是对不再使用的类进行回收。

要判定一个类是否可以被卸载,需要同时满足以下三个条件:

  • 此类所有的实例对象都已经被回收,即在堆区中不存在该类的任何实例对象和子类对象。
  • 加载该类的类加载器已经被回收。在Java中,类加载器通过ClassLoader类实现,当一个类加载器不再被引用,或者其父类加载器也被回收时,该类加载器会被回收。
  • 该类对应的java.lang.Class对象没有被其他对象引用。如果一个Class对象没有被其他任何对象引用,那么这个Class对象可以被回收。

2.手动触发垃圾回收

虽然垃圾回收是自动进行的,但在某些情况下,可能需要手动触发垃圾回收。这可以通过调用System.gc()方法实现。这个方法会向Java虚拟机发送一个请求,要求进行垃圾回收。

System.gc();

image.gif

需要注意的是,调用System.gc()并不一定会立即执行垃圾回收。Java虚拟机可能会根据当前的运行情况自行判断是否需要进行垃圾回收。因此,手动触发垃圾回收并不一定能够提高程序的性能。

在开发中,手动触发垃圾回收的情况并不常见。但在一些特殊的应用场景中,如OSGi框架和JSP的热部署等,可能需要手动触发垃圾回收。在这些场景中,当一个jsp文件被修改后,对应的类加载器会被卸载,然后重新创建类加载器并重新加载jsp文件。

3.方法区的垃圾回收案例

案例:

此类所有的实例对象都已经被回收,即在堆区中不存在该类的任何实例对象和子类对象。

public class Demo1 {
    public static void main(String[] args) throws InterruptedException {
        try {
            URLClassLoader loader = new URLClassLoader(new URL[]{new URL("file:D:\\Test\\")});
            Class<?> clazz = loader.loadClass("com.rye.test.Test");
            Object o = clazz.newInstance();
            o = null;
            System.gc();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
image.gif

image.gif

案例:

加载该类的类加载器已经被回收。在Java中,类加载器通过ClassLoader类实现,当一个类加载器不再被引用,或者其父类加载器也被回收时,该类加载器会被回收。

public class Demo1 {
    public static void main(String[] args) throws InterruptedException {
        try {
            URLClassLoader loader = new URLClassLoader(new URL[]{new URL("file:D:\\Test\\")});
            Class<?> clazz = loader.loadClass("com.rye.test.Test");
            Object o = clazz.newInstance();
            loader = null;
            System.gc();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
image.gif

image.gif

案例:

该类对应的java.lang.Class对象没有被其他对象引用。如果一个Class对象没有被其他任何对象引用,那么这个Class对象可以被回收。

public class Demo1 {
    public static void main(String[] args) throws InterruptedException {
        try {
            URLClassLoader loader = new URLClassLoader(new URL[]{new URL("file:D:\\Test\\")});
            Class<?> clazz = loader.loadClass("com.rye.test.Test");
            Object o = clazz.newInstance();
            clazz = null;
            System.gc();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
image.gif

image.gif

总结

JVM是Java程序的运行环境,负责字节码解释、内存管理、安全保障、多线程支持、性能监控和跨平台运行。本文主要介绍了Java的内存管理和自动垃圾回收、方法区的垃圾回收等内容,希望对大家有所帮助。

目录
打赏
0
0
0
0
40
分享
相关文章
JVM简介—2.垃圾回收器和内存分配策略
本文介绍了Java垃圾回收机制的多个方面,包括垃圾回收概述、对象存活判断、引用类型介绍、垃圾收集算法、垃圾收集器设计、具体垃圾回收器详情、Stop The World现象、内存分配与回收策略、新生代配置演示、内存泄漏和溢出问题以及JDK提供的相关工具。
JVM简介—2.垃圾回收器和内存分配策略
|
3月前
|
Java虚拟机(JVM)垃圾回收机制深度剖析与优化策略####
本文作为一篇技术性文章,深入探讨了Java虚拟机(JVM)中垃圾回收的工作原理,详细分析了标记-清除、复制算法、标记-压缩及分代收集等主流垃圾回收算法的特点和适用场景。通过实际案例,展示了不同GC(Garbage Collector)算法在应用中的表现差异,并针对大型应用提出了一系列优化策略,包括选择合适的GC算法、调整堆内存大小、并行与并发GC调优等,旨在帮助开发者更好地理解和优化Java应用的性能。 ####
90 0
【JVM】——GC垃圾回收机制(图解通俗易懂)
GC垃圾回收,标识出垃圾(计数机制、可达性分析)内存释放机制(标记清除、复制算法、标记整理、分代回收)
秒杀抢购场景下实战JVM级别锁与分布式锁
在电商系统中,秒杀抢购活动是一种常见的营销手段。它通过设定极低的价格和有限的商品数量,吸引大量用户在特定时间点抢购,从而迅速增加销量、提升品牌曝光度和用户活跃度。然而,这种活动也对系统的性能和稳定性提出了极高的要求。特别是在秒杀开始的瞬间,系统需要处理海量的并发请求,同时确保数据的准确性和一致性。 为了解决这些问题,系统开发者们引入了锁机制。锁机制是一种用于控制对共享资源的并发访问的技术,它能够确保在同一时间只有一个进程或线程能够操作某个资源,从而避免数据不一致或冲突。在秒杀抢购场景下,锁机制显得尤为重要,它能够保证商品库存的扣减操作是原子性的,避免出现超卖或数据不一致的情况。
112 10
JVM原理与实现——Synchronized关键字
在多线程Java程序中,`Synchronized`关键字用于确保线程安全。本文深入探讨其工作原理,通过分析字节码`monitorenter`和`monitorexit`,解释JVM如何实现同步机制。文章展示了`Synchronized`方法的编译结果,并详细解析了轻量锁和重度锁的实现过程,包括Mark Word的状态变化及CAS操作的应用。最后简要介绍了`ObjectMonitor::enter()`函数在获取重度锁时的作用。
JVM原理与实现——Synchronized关键字
Java虚拟机(JVM)垃圾回收机制深度解析与优化策略####
本文旨在深入探讨Java虚拟机(JVM)的垃圾回收机制,揭示其工作原理、常见算法及参数调优方法。通过剖析垃圾回收的生命周期、内存区域划分以及GC日志分析,为开发者提供一套实用的JVM垃圾回收优化指南,助力提升Java应用的性能与稳定性。 ####
Java虚拟机(JVM)的垃圾回收机制深度剖析####
本文深入探讨Java虚拟机(JVM)的垃圾回收机制,揭示其工作原理、常见算法、性能调优策略及未来趋势。通过实例解析,为开发者提供优化Java应用性能的思路与方法。 ####
86 1
JVM进阶调优系列(10)敢向stop the world喊卡的G1垃圾回收器 | 有必要讲透
本文详细介绍了G1垃圾回收器的背景、核心原理及其回收过程。G1,即Garbage First,旨在通过将堆内存划分为多个Region来实现低延时的垃圾回收,每个Region可以根据其垃圾回收的价值被优先回收。文章还探讨了G1的Young GC、Mixed GC以及Full GC的具体流程,并列出了G1回收器的核心参数配置,帮助读者更好地理解和优化G1的使用。
|
4月前
|
实战优化公司线上系统JVM:从基础到高级
【11月更文挑战第28天】Java虚拟机(JVM)是Java语言的核心组件,它使得Java程序能够实现“一次编写,到处运行”的跨平台特性。在现代应用程序中,JVM的性能和稳定性直接影响到系统的整体表现。本文将深入探讨JVM的基础知识、基本特点、定义、发展历史、主要概念、调试工具、内存管理、垃圾回收、性能调优等方面,并提供一个实际的问题demo,使用IntelliJ IDEA工具进行调试演示。
71 0
|
4月前
|
JVM有哪些垃圾回收算法?
(1)标记清除算法: 标记不需要回收的对象,然后清除没有标记的对象,会造成许多内存碎片。 (2)复制算法: 将内存分为两块,只使用一块,进行垃圾回收时,先将存活的对象复制到另一块区域,然后清空之前的区域。用在新生代 (3)标记整理算法: 与标记清除算法类似,但是在标记之后,将存活对象向一端移动,然后清除边界外的垃圾对象。用在老年代
38 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等