A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© HM周磊 中级黑马   /  2013-3-14 09:58  /  2474 人查看  /  10 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 HM周磊 于 2013-3-14 19:10 编辑
  1. class Wrench2
  2. {
  3.         int size;
  4.         public static void main(String[] args)
  5.         {
  6.                 Wrench2 w = new Wrench2();
  7.                 w.size = 11;//该对象运行完了,为什么没被回收。
  8.                 Wrench2 W2 = go(w,w.size);
  9.                 System.out.print(W2.size);
  10.         }
  11.         static Wrench2 go(Wrench2 wr,int s)
  12.         {
  13.                 s = 12;
  14.                 return wr;
  15.         }
  16. }
复制代码
请问大神们,int类型的size、main主函数、方法都存在哪?
在什么情况下,内存中的对象才会被当成垃圾回收。

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

10 个回复

倒序浏览
int类型的size、main主函数、方法都存在哪?
解答:都存放在内存中的main方法区中。
垃圾回收:当程序创建对象,数组等应用类型实体时,系统都会在堆内存中为之分配一块内存空间,对象就保存在这块内存空间里,当这块内存不再被任何引用变量引用时,这块内存空间就变成了垃圾,等待垃圾回收机制进行回收。
特点:
(1)垃圾回收机制只负责回收堆内存中对象,不会回收任何物理资源(比如数据库连接,网络IO等资源)
(2)程序无法精确控制垃圾回收的运行,垃圾回收会在合适的时候运行。当对象永久性地失去引用后,系统就会在适合的时候回收它所占的内存。
(3)垃圾回收机制回收任何对象之前,总会先调用它的finalize方法,该方法可能使该对象重新复活(让一个引用变量重新引用该对象),从而导致垃圾回收机制取消回收。
当一个对象在堆内存中运行时,可以将对象所处的状态分为一下三种:
(1)激活状态:当一个对象被创建后,有一个以上的引用变量引用它,则这个对象在程序中处于激活状态,程序可以通过引用变量来调用该对象的属性和方法。
(2)去活状态:如果程序中某个对象不再被任何引用变量引用它,它就进入了去活状态。在这个状态下,系统的垃圾回收机制准备回收该对象所占的内存,回收之前,系统会调用去活状态对象的finalize方法进行资源清理,如果系统在调用finalize方法重新让一个引用变量引用该对象,则这个对象会再次变为激活状态,否则该对象将进入死亡状态。
(3)当对象与所有引用的关联都被切断,其系统已经调用所有对象的finalize方法依然没有使该对象变为激活状态,这个对象将永久的失去引用,最后变为死亡状态,只有当对象处于死亡状态时,系统才会真正回收该对象所占的资源。


强制垃圾回收:
程序是无法精确控制Java垃圾回收的时间,但我们依然可以强制系统进行垃圾回收:只是这种强制只是通知系统进行垃圾回收,但系统是否进行垃圾回收这个还是不确定。当使用强制系统垃圾回收后还是会有一点效果的。
强制垃圾回收:
(1)调用System类的gc()静态方法:System.gc();
(2)调用Runtime对象的gc()实例方法:Runtime.getRuntime().gc();
经典实例:
public class Test {      
  public static void main(String[] args) {
                for(int i=0;i<3;i++){
                  new Test();                     
                  //下面两行diamond的作用完全相同,强制系统进行垃圾回收      
                  //Runtime.getRuntime().gc();                  
                  System.gc();        
            }   
  }      
  public void finalize(){            
     System.out.println("系统正在处理Test兑现的的资源...");   
   }
}
注意:强制垃圾回收仅仅只是建议系统立即进行垃圾回收,系统完全有可能并不立即进行垃圾回收,只是通知垃圾回收机制,让其尽快的进行垃圾回收。


希望对你有所帮助!

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

回复 使用道具 举报
这里我就不正面给你解答了,同样的问题有关垃圾回收机制的,我被面试了好几次,都有它出现!
最后找了一篇比较不错blog,那里介绍的很详细,这里我就不班门弄斧了,原因我也是通过他明白的,希望对你有所帮助.
地址是:
http://blog.csdn.net/raige/article/details/4893306

希望给你解惑!
回复 使用道具 举报
袁见 发表于 2013-3-14 10:07
int类型的size、main主函数、方法都存在哪?
解答:都存放在内存中的main方法区中。
垃圾回收:当程序创建对 ...

O(∩_∩)O谢谢,很有帮助!:lol
回复 使用道具 举报
沉默de羔羊 发表于 2013-3-14 10:15
这里我就不正面给你解答了,同样的问题有关垃圾回收机制的,我被面试了好几次,都有它出现!
最后找了一篇 ...

谢谢,其实我想搞清楚的是为什么打印结果是11.
想请大神们帮我分析分析。。
回复 使用道具 举报
HM周磊 发表于 2013-3-14 18:02
谢谢,其实我想搞清楚的是为什么打印结果是11.
想请大神们帮我分析分析。。 ...


Wrench2 w = new Wrench2();
w.size = 11;   ---这里不是给w对象的size属性赋值11了么?
go(w,w.size);调用的方法是

static Wrench2 go(Wrench2 wr,int s)

        {

                s = 12;--这里你只是给形参s赋值12,但是没有改变形参wr指向的w对象的size属性啊,这里要是修改正确的方法是:wr.size=12

                return wr;---你这里其实就是返回了w对象的地址

        }

Wrench2 W2 =go(w,w.size);这里其实就是把w对象赋给了W2变量。
然后你打印的W2.size,其实就是打印的w.size.

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

回复 使用道具 举报
沉默de羔羊 发表于 2013-3-14 18:21
Wrench2 w = new Wrench2();
w.size = 11;   ---这里不是给w对象的size属性赋值11了么?
go(w,w.size);调 ...


嗯,这里其实你这里的方法里:
参数wr:是典型的引用传递。wr指向的是你传过来的对象!你要是修改wr那么就是相当于修改传过来的那个对象。
参数s:是典型的值传递。这里的s作用域只是在本方法里面,出了方法就失效了。

我上面说的是白话,可能不是很正规,但是是通俗易懂的说法!
回复 使用道具 举报
沉默de羔羊 发表于 2013-3-14 18:21
Wrench2 w = new Wrench2();
w.size = 11;   ---这里不是给w对象的size属性赋值11了么?
go(w,w.size);调 ...

int s 不是等于11吗,然后不是被赋成12了吗?难道是静态方法里的所以不能赋值??
回复 使用道具 举报
HM周磊 发表于 2013-3-14 18:33
int s 不是等于11吗,然后不是被赋成12了吗?难道是静态方法里的所以不能赋值?? ...

你是把w.size的值传给了形参s,你修改形参s=12,改变的只是s的值啊,
你又没有直接修改w.size=12。

这里我需要申明的是,s接收的是个数值,不是引用类型。
回复 使用道具 举报
沉默de羔羊 发表于 2013-3-14 18:56
你是把w.size的值传给了形参s,你修改形参s=12,改变的只是s的值啊,
你又没有直接修改w.size=12。

建议你看看 java 值传递吧!你可能还分不清楚,什么是值传递和引用传递!
回复 使用道具 举报
沉默de羔羊 发表于 2013-3-14 18:57
建议你看看 java 值传递吧!你可能还分不清楚,什么是值传递和引用传递! ...

哦{:3_60:}
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马