Java内存回收

内存的分配和回收构成java的内存管理。

java内存回收几个问题:

1.JVM的垃圾回收机制采用有向图方式管理内存中的对象,不可达对象即可回收。

即:当一个java对象失去引用时,JVM的垃圾回收机制会自动清除它们,并回收它们占用的内存。

2.内存泄露

如果程序中的一些java对象,他们处于可达状态,但是程序以后永远不会访问它们,那么它们占用的内存不会被回收回来,它们占用的内存空间就产生内存泄露。

3.垃圾回收主要完成两件事:

  1)跟踪监控每一个java对象,当某个对象处于不可达状态时,回收该对象占用的内存。

  2)清理内存分配、回收过程产生的内存碎片。

4.垃圾回收的基本算法

  1)复制:将堆内存分成两个相同的空间,从根节点开始访问每一个关联的可达对象,将空间A中可达对象复制到B,然后一次性回收整个A空间。

    ----遍历成本较小,但是需要巨大的复制成本和较多的内存。

  2)标记清除:即不压缩的回收方式。垃圾回收器先从根节点开始访问所有的可达对象,将他们标记可达,然后再遍历一遍整个内存区域,把所有没有标记的对象回收。

    ----无需大规模复制,内存利用率较高,但是两次遍历堆内存,遍历成本较大,而且堆内存易产生碎片。

  3)标记压缩:即压缩方式。充分利用上述两种方式优点,垃圾回收器现从根节点开始访问所有可达对象,将他们标记为可达,接下来垃圾回收器将这些活动对象搬迁到一起,这个过程也叫内存压缩,然后垃圾回收机制再次回收那些不可达对象占用的内存,避免产生碎片。

无论采用哪种回收机制,都有利有弊。现行的垃圾回收器用分代的方式采用不同的回收算法。

两点事实:

  1)绝大多数对象不会长时间引用,这些对象会在其young期间就被回收。

  2)很老的对象(生存时间很长)和很新的对象(生存时间很短)之间很少存在引用的情况。

堆内存分三代:

  1)Young代(生存时间最短)---------采用复制算法回收(少量复制,大量回收)

  2)Old代(在Young代对象经过无数次垃圾回收仍然没被回收掉,即长时间仍然可达,转为Old代)------标记压缩算法回收(少量回收)

  3)Permanent代(主要用于装载Class、方法等信息,默认64M,通常不会回收Permanent代的对象)

5.内存管理小技巧

  1)尽量用直接量:使用字符串 Byte Integer Long Float Double Boolean Character

  2)使用StringBuilder和StringBuffer进行字符串连接:这两是可变字符串,像String也可以字符串连接,但是是不可变变量

  3)尽早释放无用引用:obj=null

  4)尽量少使用静态变量

  5)避免在经常调用的方法、循环中创建java对象

  6)缓存经常使用的对象

  7)尽量不要使用finalize方法

  8)考虑使用softReference(软指针)

原文地址:https://www.cnblogs.com/xunyingFree/p/7424337.html