java的内存回收--读《疯狂java》 笔记

本文详细探讨了Java的内存回收机制,包括强引用、软引用、弱引用和虚引用的概念及其区别。介绍了垃圾回收的目标、过程,以及如何避免内存泄漏。此外,文章还分析了不同代的内存分配,如年轻代、老年代和永久代,并讨论了各种垃圾回收器,如串行回收器、并行回收器和CMS回收器的工作原理和特点。最后,分享了一些内存管理的小技巧,如使用直接量、StringBuilder和StringBuffer、尽早释放无用对象引用等,以优化内存使用和提高程序性能。
摘要由CSDN通过智能技术生成


程序员需要通过关键字new创建Java对象,即可视作为Java对象申请内存空间,JVM会在堆内存中为每个对象分配空间;当一个Java对象失去引用时,JVM的垃圾回收机制会自动清除它们,并回收它们所占用的内存空间。
对于JVM的垃圾回收机制来说,是否回收一个对象的标准在于:是否还有引用变量引用该对象?只要有引用变量引用该对象,垃圾回收机制就不会回收它。

也就是说,当Java对象被创建出来之后,垃圾回收机制会实时地监控每一个对象的运行状态,包括对象的申请、引用、被引用、赋值等。当垃圾回收机制实时地监控到某个对象不再被引用变量所引用时,立即回收机制就会回收它所占用的空间。

基本上,可以把JVM内存中对象引用理解成一种有向图,把引用变量、对象都当成为有向图的顶点,将引用关系当成图的有向边,有向边总是从引用端指向被引用的Java对象。因为Java所有对象都是由一条一条线程创建出来的,因此可把线程对象当成有向图的起始顶点。

对于单线程程序而言,整个程序只有一条main线程,那么该图就是以main进程为顶点的有向图。在这个有向图中,main顶点可达的对象都处于可达状态,垃圾回收机制不会回收它们;如果某个对象在这个有向图中处于不可达状态,那么就认为这个对象不再被引用,接下来垃圾回收机制就会主动回收它了。

当一个对象在堆内存中运行时,根据它在对应有向图中的状态,可以把它所处的状态分成如下3种。

  • 可达状态:当一个对象被创建后,有一个以上的引用变量引用它。在有向图中可从起始顶点导航到该对象,那它就处于可达状态,程序可通过引用变量来调用该对象的属性和方法。
  • 可恢复状态:如果程序中某个对象不再有任何引用变量引用它,它将先进入可恢复状态,此时从有向图的起始顶点不能导航到该对象。在这个状态下,系统的垃圾回收机制准备回收该对象所占用的内存。在回收该对象之前,系统会调用可恢复状态的对象的finalize方法进行资源清理,如果系统在调用finalize方法重新让一个以上引用变量引用该对象,则这个对象会再次变为可达状态;否则,该对象将进入不可达状态。
  • 不可达状态:当对象的所有关联都被切断,且系统调用所有对象的finalize方法依然没有使该对象变成可达状态,那这个对象将永久性地失去引用,最后变成不可达状态。只有当一个对象处于不可达状态时,系统才会真正回收该对象所占有的资源
  • 在这里插入图片描述

引用

对垃圾回收机制来说,判断一个对象是否可回收的标准就在于该对象是否被引用,因此引用也是JVM进行内存管理的一个重要概念。为了更好地管理对象的引用,从JDK 1.2开始,Java在java.lang.ref包下提供了3个类:SoftReference 、PhantomReference和WeakReference。它们分别代表了系统对对象的3种引用方式:软引用、虚引用和弱引用。归纳起来,Java语言对对象的引用有如下4种。

  • 强引用
  • 软引用
  • 弱引用
  • 虚引用

强引用

这是Java程序中最常见的引用方式,程序创建一个对象,并把这个对象赋给一个引用变量,这个引用变量就是强引用。

Java程序可通过强引用来访问实际的对象,前面介绍的程序中的所有引用变量都是强引用的方式。当一个对象被一个或一个以上的强引用变量所引用时,它处于可达状态,它不可能被系统垃圾回收机制回收。

强引用是Java编程中广泛使用的引用类型,被强引用所引用的Java对象绝不会被垃圾回收机制回收,即使系统内存非常紧张;即使有些Java对象以后永远都不会被用到,JVM也不会回收被强引用所引用的Java对象。

由于JVM肯定不会回收强引用所引用的Java对象,因此强引用是造成Java内存泄漏的主要原因之一。

软引用

软引用需要通过SoftReference类来实现,当一个对象只具有软引用时,它有可能被垃圾回收机制回收。对于只有软引用的对象而言,当系统内存空间足够时,它不会被系统回收,程序也可使用该对象;当系统内存空间不足时,系统将会回收它。
软引用通常用于对内存敏感的程序中,软引用是强引用很好的替代。 对于软引用则不同,当系统内存空间充足时,软引用与强引用没有太大的区别;当系统内存空间不足时,被软引用所引用的Java对象可以被垃圾回收机制回收,从而避免系统内存不足的异常。

当程序需要大量创建某个类的新对象,而且有可能重新访问已创建老对象时可以充分使用软引用来解决内存紧张的难题。

    class Person 
    {
    
          String name; 
          int age; 
          public Person(String name , int age) 
          {
    
                this.name = name; 
                this.age = age; 
          } 
          public String toString() 
          {
    
                return "Person[name = " + name 
                      + ", age = " + age + "]"; 
          } 
    } 
    public class SoftReferenceTest 
    {
    
          public static void main(String[] args)  
          {
    
                SoftReference<Person>[] people =  
                     new SoftReference[100]; 
                for (int i = 0 ; i < people.length ; i + +) 
                {
    
                      people[i] = new SoftReference<Person>(new Person( 
                           "名字" + i , (i + 1) * 4 % 100)); 
                } 
                System.out.println(people[2].get()); 
                System.out.println(people[4].get
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ynchyong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值