使用Java VisualVM观察过期对象引用现象

《Effective Java》书中第7条中提到:一般来说,只要类是自己管理内存,程序员就应该警惕内存泄漏问题。一旦元素被释放掉,则该元素中包含的任何对象引用都应该被清空。

此次测试过程我用的jdk8,在jdk的bin目录下可以找到jvisualvm.exe,双击打开。

idea设置堆内存限制-Xmx100M -Xms100M ,如下图所示

测试代码如下:

java 复制代码
import java.util.Arrays;
import java.util.EmptyStackException;

public class Stack {
    private Object[] elements;
    private int size = 0;
    private static final  int DEFAULT_INITIAL_CAPACITY = 16;

    public Stack(){
        elements = new Object[DEFAULT_INITIAL_CAPACITY];
    }

    public void push(Object e){
        ensureCapacity();
        elements[size++] = e;
    }

    public Object pop(){
        if(size == 0){
            throw new EmptyStackException();
        }
        Object element = elements[--size];
        return element;
    }

    private void ensureCapacity(){
        if(elements.length == size){
            elements = Arrays.copyOf(elements, 2 * size +1);
        }
    }
}
java 复制代码
public class ObsoleteReferenceTest {
    public static void main(String[] args) throws InterruptedException {
        Stack stack = new Stack();
        // 压入大量大对象
        for (int i = 0; i < 80; i++) {
            stack.push(new byte[1024 * 1024]);
            System.out.println("压入第 " + i + " 个 1MB 数组");
        }
        // 全部弹出!业务上不再使用这些对象
        for (int i = 0; i < 80; i++) {
            stack.pop();
        }
        System.out.println("所有对象pop完成,业务层面不再使用");

        Thread.sleep(30000);
    }
}

运行代码后,进入Java VisualVM,在左侧找到当前代码运行的程序,双击,然后点击右侧上方的"监视",如下图所示

等待idea控制台输出 所有对象pop完成,业务层面不再使用 后点击"执行垃圾回收"按钮,如下图所示,可以看到,堆内存的使用量并没有明显下降。说明elements 数组内部仍然持有大量byte对象引用。

修改pop()方法,手动清空过期引用

typescript 复制代码
public Object pop(){
    if(size == 0){
        throw new EmptyStackException();
    }
    Object element = elements[--size];
    //手动清空过期引用
    elements[size] = null;
    return element;
}

再次运行代码,点击执行垃圾回收,观察堆使用情况,等待idea控制台输出 所有对象pop完成,业务层面不再使用 后点击"执行垃圾回收"按钮,可以看到堆使用量大幅下降,说明大量过期对象已被回收。

相关推荐
步行cgn12 小时前
Spring Boot 绑定嵌套 Bean 详解
java·spring boot·后端
phltxy21 小时前
C语言操作符详解
java·c语言·算法
步行cgn1 天前
@Configuration 详解:Spring 配置类的核心注解
java·后端·spring
sunshine22 girl1 天前
Java学习一 环境配置2 安装和基本使用Idea
java·学习·intellij-idea
嘿嘿-661 天前
Windows 一键使用 GPT-6 Astra:Codex CLI 配置教程
java·人工智能·windows·gpt·chatgpt·web
策案案案1 天前
YOLO: 将AI Agents嵌入到IntelliJ IDEA
java·大数据·人工智能·笔记·yolo·microsoft·intellij-idea
辰烨chenye1 天前
LeetCode Hot 100 题解 · 堆篇
java·算法·leetcode
shehuiyuelaiyuehao1 天前
算法29,前缀和,除自身以外的数组的乘积
java·数据结构·算法
小刘在重生~1 天前
Java常用类|String类详解 + BigDecimal精准计算(含面试题)
java·开发语言·python
随遇而安zx1 天前
【多线程】---JMM 与 volatile 深度解析
java·多线程