`

Java内存管理(二、Java垃圾回收)

阅读更多

二、Java垃圾回收
1. JVM运行环境中垃圾对象的定义

     一个对象创建后被放置在JVM的堆内存中,当永远不再引用这个对象时,它将被JVM在堆内存中回收。或  当对象在JVM运行空间中无法通过根集合(root set)到达时,这个对象就被称为垃圾对象。
2. 堆内存
* 在JVM启动时被创建;堆内存中所存储的对象可以被JVM自动回收,不能通过其他外部手段回收
* 堆内存可分为两个区域:新对象区和老对象区
    -- 新对象区可分为三个小区:Eden区、From区、To区
    Eden区用来保存新创建的对象,当Eden区中的对象满了之后,JVM将会做可达性测试,检测有哪些对象由根集合出发是不可达的,不可达的对象就会被JVM回收,并将所有的活动对象从Eden区拷到To区,此时一些对象将发生状态交换,有的对象就从To区被转移到From区。
3. JVM中对象的生命周期
 * 创建阶段(步骤)
    -- 为对象分配存储空间
    -- 开始构造对象
    -- 递归调用其超类的构造方法
    -- 进行对象实例初始化与变量初始化
    -- 执行构造方法体
 * 应用阶段
    -- 特征:系统至少维护着对象的一个强引用;所有对该对象引用强引用(除非显示声明为其它引用)
    -- 强引用
      指JVM内存管理器从根引用集合出发,遍寻堆中所有到达对象的路径。当到达某对象的任意路径都不含有引用对象时,对这个对象的引用就被称为强引用。
当内存不足时,JVM宁愿抛出OutOfMemeryError错误使程序停止,也不会靠收回具有强引用的对象来释放内存空间
    -- 软引用
      它能实现cache功能,防止最大限度的使用内存时引起的OutOfMemory异常,在内存不够用的时候jvm会自动回收Soft Reference。
软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收,java虚拟机就会把这个软引用加入到与之关联的引用队列中。
      Java中提供软引用的包:java.lang.ref.SoftReference(后续详解)
     软引用
      实现cache功能,防止最大限度的使用内存时引起的OutOfMemory异常,在内存不够用的时候jvm会自动回收Soft Reference.软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。

import java.lang.ref.SoftReference
//实现cache功能,最大限度利用内存
Test test = new Test();
SoftReference sr = new SoftRefence(test);
test = null;
if(sr.get() != null){
     test = sr.get();
}else{
     test = new Test();
     sr = new SoftReference(test);
     test = null;
}
//创建一个强引用
String str = new String("hello"); 
//创建引用队列, <String>为范型标记,表明队列中存放String对象的引用
ReferenceQueue<String> rq = new ReferenceQueue<String>(); 
//创建一个弱引用,它引用"hello"对象,并且与rq引用队列关联
//<String>为范型标记,表明WeakReference会弱引用String对象
SoftReference<String> wf = new SoftReference<String>(str, rq);
str=null; //取消"hello"对象的强引用
String str1=wf.get(); //假如"hello"对象没有被回收,str1引用"hello"对象
//假如"hello"对象没有被回收,rq.poll()返回null
Reference<? extends String> ref=rq.poll(); 

    -- 弱引用
      只具有弱引用的对象有更短的生命周期,无论内存是否紧张,被垃圾回收器发现立即回收。弱引用可以和一个引用队列(ReferenceQueue)联合使用。
      可分为长弱引用和短弱引用,长弱引用在对象的Finalize方法被GC调用后依然追踪对象
      Java中提供弱引用的包:java.lang.ref.WeakReference
    -- 虚引用
      虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。虚引用主要用来跟踪对象被垃圾回收的活动。
      Phantom对象指一些执行完了finalize函数,并且为不可达对象,但是还没被GC回收的对象。这种对象可以辅助finalize进行一些后期的回收工作。
 * 不可视阶段
    -- 如果一个对象已使用完,并且在其可视区域不再使用,应该主动将其设置为null,即obj=null;这样可以帮助JVM及时地发现这个垃圾对象,并且可以及时地挥手该对象所占用的系统资源。

package reference;
/*  
WeakHashMap, 在这种Map中存放了键对象的弱引用,当一个键对象被垃圾回收,那么相应的值对象的引用会从Map中删除。WeakHashMap能够节约存储空间,可用 来缓存那些非必须存在的数据。  
*/
import java.util.*;
import java.lang.ref.*;

class Key {
 String id;
 public Key(String id) {
  this.id = id;
 }
 public String toString() {
  return id;
 }

 public int hashCode() {
  return id.hashCode();
 }

 public boolean equals(Object r) {
  return (r instanceof Key) && id.equals(((Key) r).id);
 }

 public void finalize() {
  System.out.println("Finalizing Key " + id);
 }
}

class Value {
 String id;

 public Value(String id) {
  this.id = id;
 }

 public String toString() {
  return id;
 }

 public void finalize() {
  System.out.println("Finalizing Value " + id);
 }
}

public class MapCache {
 public static void main(String[] args) throws Exception {
  int size = 1000;
  // 或者从命令行获得size的大小
  if (args.length > 0)
   size = Integer.parseInt(args[0]);

  Key[] keys = new Key[size]; // 存放键对象的强引用
  WeakHashMap<Key, Value> whm = new WeakHashMap<Key, Value>();
  for (int i = 0; i < size; i++) {
   Key k = new Key(Integer.toString(i));
   Value v = new Value(Integer.toString(i));
   if (i % 3 == 0)
    keys[i] = k; // 使Key对象持有强引用
   whm.put(k, v); // 使Key对象持有弱引用
  }
  // 催促垃圾回收器工作
  System.gc();

  // 把CPU让给垃圾回收器线程
  Thread.sleep(8000);
 }
}

 
4. Java中的析构方法finalize
    finalize()方法常称之为终止器
          protected void finalize(){
              // finalization code here
         }
    对象即将被销毁时,有时需要做一些善后工作。可以把这些操作写在finalize()方法里。
    Java终止器却是在对象被销毁时调用。一旦垃圾收集器准备好释放无用对象占用的存储空间,它首先调用那些对象的finalize()方法,然后才真正回收对象的内存。而被丢弃的对象何时被销毁,应用是无法获知的。大多数场合,被丢弃对象在应用终止后仍未销毁。到程序结束的时候,并非所有收尾模块都会得到调用。

5. 应用能干预垃圾回收吗?
    在应用代码里控制JVM的垃圾回收运作是不可能的事。
    对垃圾回收有两个途径。第一个就是将指向某对象的所有引用变量全部移走。这就相当于向JVM发了一个消息:这个对象不要了。第二个是调用库方法System.gc()。第一个是一个告知,而调用System.gc()也仅仅是一个请求。JVM接受这个消息后,并不是立即做垃圾回收,而只是对几个垃圾回收算法做了加权,使垃圾回收操作容易发生,或提早发生,或回收较多而已。
    希望JVM及时回收垃圾,是一种需求。其实,还有相反的一种需要:在某段时间内最好不要回收垃圾。要求运行速度最快的实时系统,特别是嵌入式系统,往往希望如此。
    Java的垃圾回收机制是为所有Java应用进程服务的,而不是为某个特定的进程服务的。因此,任何一个进程都不能命令垃圾回收机制做什么、怎么做或做多少。

6. 垃圾回收算法
* 引用计数
    该算法在java虚拟机没被使用过,主要是循环引用问题,因为计数并不记录谁指向他,无法发现这些交互自引用对象。
    -- 怎么计数?
        当引用连接到对象时,对象计数加1
        当引用离开作用域或被置为null时减1
    -- 怎么回收?
        遍历对象列表,计数为0就释放
    -- 有什么问题?
        循环引用问题。
* 标记算法
    标记算法的思想是从堆栈和静态存储区的对象开始,遍历所有引用,标记活得对象。
    对于标记后有两种处理方式:
  (1) 停止-复制
    -- 所谓停止,就是停止在运行的程序,进行垃圾回收
    -- 所谓复制,就是将活得对象复制到另外一个堆上,以使内存更紧凑
    -- 优点在于,当大块内存释放时,有利于整个内存的重分配
    -- 有什么问题?
        一、停止,干扰程序的正常运行,二,复制,明显耗费大量时间,三,如果程序比较稳定,垃圾比较少,那么每次重新复制量是非常大的,非常不合算
    -- 什么时候启动停止-复制?
        内存数量较低时,具体多低我也不知道
  (2) 清除 也称标记-清除算法
    -- 也就是将标记为非活得对象释放,也必须暂停程序运行
    -- 优点就是在程序比较稳定,垃圾比较少的时候,速度比较快
    -- 有什么问题?
       很显然停止程序运行是一个问题,只清除也会造成很对内存碎片。
    -- 为什么这2个算法都要暂停程序运行?
       这是因为,如果不暂停,刚才的标记会被运行的程序弄乱

 

分享到:
评论

相关推荐

    java内存管理与垃圾回收

    java内存管理与垃圾回收

    JAVA内存模型与垃圾回收

    JAVA内存模型与垃圾回收 JAVA内存模型与垃圾回收 JAVA内存模型与垃圾回收

    java垃圾回收及内存泄漏.pptx

    java 垃圾回收机制 内存泄漏 技术分享 相关技术分享

    Java内存管理机制

    1、JAVA 内存管理总结 2、Java的内存管理实例 3、垃圾回收机制:

    java入门、java内存区域和OOM、垃圾回收器和垃圾回收策略

    java 入门、java内存区域和OOM、垃圾回收器和垃圾回收策略

    Java内存与垃圾回收调优.docx

    Java内存与垃圾回收调优,Java内存与垃圾回收的调优是一个重要的主题,特别是在高性能和大规模的应用程序中。以下是一些关键的调优建议和步骤: 理解内存结构: Java堆是主要的内存区域,用于存储对象实例。 堆内存...

    java 垃圾回收 机制详解

    说起垃圾收集(Garbage Collection,GC),大部分人都把这项技术当做Java语言的伴生产物。经过半个世纪的发展,内存的动态分配与内存回收技术已经相当成熟,一切看起来都进入了“自动化”时代,那为什么我们还要去...

    java内存管理详细介绍.doc

    本文档主要讲述的是java内存管理详细介绍;对于从事C、C++程序开发的开发人员来说,在内存管理领域,他们即是拥有最高权力的皇帝又是执行最基础工作的劳动人民——拥有每一个对象的“所有权”,又担负着每一个对象...

    Java垃圾回收知识,垃圾回收资料

    重要性:垃圾回收是Java垃圾回收器的核心功能,对性能和内存管理至关重要。准确理解垃圾回收的原理和机制,以及能够优化和调优垃圾回收过程的能力,是一个Java开发者必备的基本技能。 面试中可能会问到的垃圾回收...

    JAVA性能调优之内存管理

    java 性能调优,主要从java内存管理方面,介绍了java的内存管理,垃圾回收(GC),调优注意事项等方面系统的介绍了java的内存管理机制。

    java 垃圾回收机制详细介绍

    它把程序员从手工回收内存空间的繁重工作中解脱了出来。在SUN公司的Java程序员(Java Programmer)认证考试中,垃圾收集器是必考的内容,一般最多可以占总分值的6%左右。但是由于SUN公司的Java Programming Language...

    Java内存分配及垃圾回收文章汇总

    Java内存分配及垃圾回收文章汇总

    高吞吐低延迟Java应用的垃圾回收优化

    高吞吐低延迟Java应用的垃圾回收优化 高吞吐低延迟Java应用的垃圾回收优化 高吞吐低延迟Java应用的垃圾回收优化 高吞吐低延迟Java应用的垃圾回收优化 高吞吐低延迟Java应用的垃圾回收优化 高吞吐低延迟Java应用的...

    Java垃圾回收机制和内存分配

    你认真演示了一遍,你就能明白JAVA的垃圾回收机制。当然文档写的不一定全面,比如文档当中关于老年区少年区有一页写的不是很完整,我也没有添加太多进去,但是还是很有很全面很有参考意义的。

    灵巧指针与垃圾回收(Java、C#、C++)

    在JAVA 和 C# 中都有垃圾回收功能,程序员在分配一段内存后可以不再理会,而由垃圾回收自动回收,从而使程序员从复杂的内存管理中解脱出来。这是JAVA 和 C#的一大优点。而C++程序员在用 new 分配了一段内存后,还...

    Java垃圾回收详解

    垃圾回收 对象是使用new创建的, 但是并没有与之相对应的delete操作来回收对象占用的内存. 当我们完成对某个 对象的使用时, 只需停止该对象的引用: -&gt;将引用改变为指向其他对象 -&gt;将引用指向null -&gt;从方法中返回, ...

    java垃圾回收以及jvm参数调优概述

    Java技术体系中所提倡的自动内存管理最终可以归结为自动化地解决了两个问题:给对象分配内存以及回收分配给对象...本文主要对java垃圾回收机制以及jvm参数等方面做个综述,也算是自己做开发这几年对这方面的一个总结。

    java垃圾回收知识全集

    Java 垃圾回收(Garbage Collection,简称 GC)是现代编程语言中的重要特性,为开发人员提供了自动化内存管理的能力。它通过自动识别和回收不再使用的内存,减轻了程序员手动释放内存的负担,提高了应用程序的稳定性...

    JVM内存段分配,Java垃圾回收调优,Heap设定

    JVM内存段分配,Java垃圾回收调优,Heap设定

    关于java内存管理的一些理解

    主要关于java虚拟机的运行时数据区域,参考了周志明的深入理解java虚拟机,还涉及到了native方法、垃圾回收机制等等。

Global site tag (gtag.js) - Google Analytics