JAVA学习之4 引用与JVM

9.10 16:34修改:这篇文章写的更好http://blog.csdn.net/ocean181/article/details/7232759;不过最后的例子没有看懂

1.java内存管理分为内存分配和内存回收,都不需要程序员负责。

2.垃圾回收的机制主要是看对象是否有引用指向该对象。
  java对象的引用包括
  强引用
  软引用
  弱引用
  虚引用

3.强引用
  是指创建一个对象并把这个对象赋给一个引用变量。
  强引用有引用变量指向时永远不会被垃圾回收。即使内存不足的时候。
4.软引用
  软引用通过SoftReference类来实现

  软引用的对象当系统内存充足时和强引用没有太多区别,但内存不足时会回收软引用的对象。

  很多对象,但是只有一个引用指向他们(可分别指定)

   public static void main(String[] args){
  //创建软引用数组
  SoftReference<Person> [] p = new SoftReference[100]; //100000
  //赋值  
  for(int i = 0; i< p.length ;i++){
   p[i] = new SoftReference<Person>(new Person("name"+i ,i));
  }
  
  //测试
  System.out.println(p[1].get());
  System.out.println(p[4].get());
  //通知系统进行回收
  System.gc();
  System.runFinalization();
  
  System.out.println("---------------");
  System.out.println(p[1].get());
  System.out.println(p[4].get());
 }
 

    当系统内存充足时,系统不会进行软引用的内存回收,
    当系统不足时将会回收软引用的对象。

    当用 java -Xmx1m -Xms1m SoftReferenceTest 命令时强制堆内存为1m时 软引用引用对象
    将被回收。(可以创建10000个对象)

 
5.weakReference
    弱引用通过weakReference类来实现

    public static void main(String[] args) {
   String str = new String("JAVA讲义");
//   String str = "JAVA讲义"; 这种创建是在常量池中
   //创建一个如引用对象 指向 str对象
   WeakReference<String> wr = new WeakReference<String> (str);
  
   str =null;
   //输出
   System.out.println(wr.get());//JAVA讲义
   //强制垃圾回收
   System.gc();
   System.out.println(wr.get());//null
 }

 弱引用具有很强的不确定性。因为垃圾回收每次都会回收弱引用的对象。

6.虚引用
   软引用和弱引用可以单独使用,虚引用不能单独使用,需引用的作用是就跟踪对象被垃圾回收的
   状态,程序可以通过检测与虚引用关联的虚引用队列是否已经包含了指定的虚引用,从而了解
   虚引用的对象是否即将被回收。
   PhantomReference对象实现

   虚引用通过PhantomRefence类实现,它本身对对象没有影响,类似与没有应用,对象甚至感觉不到
   虚引用的存在,如果一个对象只有一个虚引用存在,那么他就类似没有应用存在。

    public static void main(String[] args){
  // 创建一个对象
  String str = new String("JAVA讲义");
//  创建一个引用队列
  ReferenceQueue<String> rq = new ReferenceQueue<String>();
  //创建一个虚引用,指定引用对象.不能单独使用必须关联引用队列
  PhantomReference pr = new PhantomReference(str,rq);
  //切断强引用
  str =null;
         //试图取得虚引用对象
  System.out.println(pr.get());
  
  //垃圾回收
  System.gc();
  System.runFinalization();
  //取出引队列中的最先进入队列的引用与pr进行比较
  System.out.println(rq.poll()==pr);
  
 }
 //null
        //true
    当程序强制垃圾回收后,只有虚引用引用字符串对象将会被垃圾回收,当被引用的对象被回收后,
    对应的引用将被添加到关联的引用队列中。

  7.如果使用软引用,弱引用,虚引用的引用方式引用对象,垃圾回收就能够随意的释放这些对象,
    若果希望尽可能减小程序在起声明周期中所占用的内存大小,可以灵活使用这些引用。

    如果使用了这些引用就不能保留这些对象的强引用(强制引用应该置null),否则就浪费了这些类提供的任何好处。

 

 

 

System.gc(); 
//告诉垃圾收集器打算进行垃圾收集,而垃圾收集器进不进行收集是不确定的 

System.runFinalization(); 
//强制调用已经失去引用的对象的finalize方法 

System.gc(); hints the VM that it is probably time to activate the Thread doing to the Garbage Collection. So all the part of this sentence stands in the hint word. The finalizer are run according to the VM good will, generally speaking. This means they could be run or could not. Invoking the System.runFinalization( ); force the VM to invoke on each instance the finalizer when it Garbage collects the Object referenced