test1()里面的innserStr,str,xml2当test1()结束的时候已经是释放了,其他全局变量的释放和回收,我想应该是像java的 gc 机制一样

解决方案 »

  1.   

    不同的意见现在到了:按 Reve(仨仁仕) 的说法,那么:  当执行完test1后,str ,tt,xml应该还有数据,xml2,innerStr所用的内存将回收。
     
     
    但按 qiushuiwuhen(秋水无恨) 的说法,那么:  当执行完test1后,str的内存应该释放,而xml,xml2所用的内存将不进行回收。不用delete语句的话,将无法回收改内存!不晓的到底是真么回事?还有上面的哪两个全局变量outStr,outStr2不晓得在哪是放?
      

  2.   

    http://caucuscare.com/~roth/JAVASCRIPT/ch11_07.htm
    11.7 Garbage Collection
    In any programming language in which you can dynamically create new objects (such as with the new operator in JavaScript) there must be some form of "garbage collection"--a way of reclaiming the memory occupied by objects that are no longer in use. In C and C++, garbage collection is manual--the programmer explicitly decides when to free memory for reuse. In Java, on the other hand, garbage collection is handled automatically--the system can detect when objects are no longer in use and free them appropriately. JavaScript also supports automatic garbage collection. In Internet Explorer 3.0, garbage collection is implemented in a technically sound way and you don't have to understand any of its details--it is enough to know that when your objects are no longer in use, the memory they occupy will automatically be reclaimed by the system. Navigator 4.0 will also have a perfectly transparent garbage collection scheme like this. Unfortunately, garbage collection in earlier versions of Navigator is less than perfect. In Navigator 3.0, it is pretty good, but requires you to be aware of a couple of issues. In Navigator 2.0, garbage collection is seriously flawed, and you must take a number of steps to avoid crashing the browser! The following subsections provide the details===========other links:
    Using JavaScript's Built-in Objects
    http://www.javaworld.com/javaworld/jw-05-1996/jw-05-javascript.htmlhttp://safari.oreilly.com/main.asp?bookname=jscript3&snode=118
      

  3.   

    xml2和innerStr都是局部变量,出了test1自然就销毁了,
    虽然没用delete,但VC中可通过析构函数等方法销毁好像没什么不同的意见呀,呵呵
      

  4.   

    对象的稍微有些不一样,因为实质上对象的内存是通过COM的底层库管理的. 
    脚本只是获得的一个接口,在离开作用域后,接口指针被自动释放
    全局变量在窗口关闭后释放.
      

  5.   

    java 的定义是,只有当对象没有被任何引用引用时才会被释放!所以按java的垃圾回收机制,当执行玩test1时
     tt  str  xml outStr ; outStr2; 都不释放!而在c++中new 分配的必须用delete 才能释放,当执行玩test1时
    new 分配的内存将不释放,更不懂得是tt居然引用了test1()栈中的
    内存!onestab(┼─) 的回答比较满意!
    不过还有一点不明白,是不是var outStr = "sfsf";
    var outStr2 = new String("ssssssss");两种写法都一样?它们的释放是在page跳转后,还是在整个ie close后释放呢?
    用delete能不能强制它释放?
      

  6.   

    yonghengdizhen(离散数学(学习中,请勿打扰)) :那么没有使用com的时候怎么处理呢?
    比如自定义对象,String对象?
      

  7.   

    我觉得局部变量应该是函数结束就回收
    全局变量应该有引用计数,当计数为0就自动销毁,如:var Obj = new Object(1,2,3);
    ...
    //假设中间Obj没有赋值给任何别的变量
    ...
    Obj = new Object(4,5,6);
    //此赋值使得不再有任何引用指向第一次创建的对象
    //所以那个对象的空间应该被回收否则就只能等到脚本结束才回收全局变量应该是在Heap上分配
    局部变量从实现角度,可以在Stack(应该更好),也可以在Heap
      

  8.   

    看来你没仔细研究过VC,严格上是都需要delete,但VC给你包装了很多,所以才能不用delete就能销毁,当然只是一些类,所以我说的是VC,而不是C++而Com的IUnknown接口也有AddRef和Release,好像扯远了...ps.不知道你听过const char[]和const CString的区别没
      

  9.   

    就是定义了一个变量,没有用就自动释放。遇到复杂的链JSCRIPT也有响应的方法释放。
    就这样了。
      

  10.   

    <script>
    var tt = null;
    var str = null;
    var xml = null;
    var outStr = "sfsf";
    var outStr2 = new String("ssssssss");function test1(){
      tt = new Date();
      xml = new ActiveXObject("Msxml2.DOMDocument");
      xml.loadXML("<root/>");
      var innerStr = "Good Lucky";
      var str = "ssssss";
      var xml2 = new ActiveXObject("Msxml2.DOMDocument");
    }
    test1();
    document.write(tt + "<br/>");
    document.write(str + "<br/>");
    document.write(xml);document.write("" + "<br/>");
    alert(xml);
    document.write(outStr + "<br/>");
    document.write(outStr2 + "<br/>");
    //document.write(innerStr + "<br/>"); // variables inside the test1()
    //document.write(str + "<br/>");
    //document.write(xml2 + "<br/>");
    </script>result:
    Wed Sep 11 19:58:25 UTC+0800 2002
    null
    undefined  /** here alert() shows : [object] **/
    sfsf
    ssssssssYou can remove the above // to see if there is anything wrong with it.
      

  11.   

    多谢!现在我明白了javascript 的内存管理跟java 是一样了,就是当对象没有被引用是,其内存将会被自动回收!不晓得对否?还有一点不明白的是全局变量在哪被回收?
      

  12.   

    何谓脚本结束?是page跳跳转?还是 id close?
      

  13.   

    1、我想对于函数调用得解决机只是相同的,也就是函数的调用实际就是不断地压栈和退栈,依次进行,当调用到某函数时,就把它的局部变量压栈,调用结束就会自动退栈(也就是在此时销毁)。你给的例子由于使用的变量为全局变量,所以只有到浏览器关闭时才会销毁,除非你手动销毁。
    2、new是分配到堆里的,这好像BCB,你可以看到通过new创建的实例需要手动delete销毁,在这里当浏览器关闭时也会释放。假设,new分配到栈中,那么你将无法使用delete方法手动退栈(也就是销毁),因为栈定义为后进先出的原则。
    这跟解释执行和编译执行没有必然联系。我想我说清楚了。
    =============================================  ∧ ∧
    ( ⊙_⊙ ) 祝所有人好运!我会天天Happy的。
      

  14.   

    强烈同意{
     回复人: yonghengdizhen(离散数学(学习中,请勿打扰)) (  ) 信誉:97  2002-09-11 18:03:00  得分:0  
     
     
      对象的稍微有些不一样,因为实质上对象的内存是通过COM的底层库管理的. 
    脚本只是获得的一个接口,在离开作用域后,接口指针被自动释放
    全局变量在窗口关闭后释放.}
    的说法,牛比,就是这么回事,你说的那个对象的实例就是这么销毁得,当你做组件时,人们往往会提供多个接口(你看些设计模式的书就知道了),其中之一就是为了照顾脚本。秋水姐 对于你那两个字符串变量的解释“不知道你听过const char[]和const CString的区别没”牛,就是这么回事(有时间看些基础的书籍)。
    =================================================
    最后告诉你,无论什么语言就象yonghengdizhen(离散数学(学习中,请勿打扰)) 所说,没有任何本质区别(看些数据结构和编译原理的书就知道了),
    <script>
    //全局
    var tt = null;
    var str = null;
    var xml = null;
    var outStr = "sfsf";
    var outStr2 = new String("ssssssss");function test1(){
      tt = new Date();//全局
      xml = new ActiveXObject("Msxml2.DOMDocument");//全局
      xml.loadXML("<root/>");//全局
      //局部,调用开始在调用函数中压栈,调用结束退栈
      var innerStr = "Good Lucky";
     /*局部,调用开始在调用函数中压栈,调用结束退栈,c++中以char[]形式存放,
      如果是var outStr2 = new String("ssssssss");则以存放于类的实例中,对于不同编译器BCB||vc有不同的类。
      不过好像在js中都是后者,只是解释器隐式的为你做了
     */
      var str = "ssssss";//局部,在堆中,并且由delete方法实施销毁,因为只有此方法知道如何销毁,这一般在com中被重载
      var xml2 = new ActiveXObject("Msxml2.DOMDocument");
    }
    </script>我的解释也许不正确,但是你在书中一定可以找到答案,多看书有好处。js 不必关心如此问题,因为浏览器位你做的很好了,就算知道了,你也没有办法通过js对他们进行操作。
      

  15.   

    从VC角度讲,还有Idle()(即窗口空闲时)会有类似gb的操作,其实只有c++和VC等底层操作语言才需要关心内存管理,因为高层操作语言已经封装挺好的
      

  16.   

    秋水是女的?
    佩服ing  !to llrock(百乐宝):////////////////////////////////////////////////////////////////////
    1、我想对于函数调用得解决机只是相同的,也就是函数的调用实际就是不断
    地压栈和退栈,依次进行,当调用到某函数时,就把它的局部变量压栈,调用
    结束就会自动退栈(也就是在此时销毁)。你给的例子由于使用的变量为全局
    变量,所以只有到浏览器关闭时才会销毁,除非你手动销毁。
    ////////////////////////////////////////////////////////////////////那么说只要浏览器不关闭!
    即使page跳转后,我也可以引用js中的全局变量了!
    我看到过有人实现了它,类似于jsp,asp中的session变量!
    但我不晓得它是怎么弄得!
    它用DHTML htc文件来把该功能封装的!js如何实现类似于jsp,asp中的session作用域变量功能!
      

  17.   

    to qiushuiwuhen(秋水无恨):
    是的!
    不过了解一下这方面的内容!
    可能代码效率会高些!这里还后点疑问:
    大家看看
    ////////////////////////////////////////////////////////////////////
    ///
    <script>
    var t1 = null;
    var t2 = null;function test(){
      var temp1 = "lucky";
      var temp2 = new String("lucky2");
      t1 = temp;
      t2 = temp2;
    }
    </script>
    ///
    ////////////////////////////////////////////////////////////////////猜猜看!test结束后temp1,temp2会不会释放?
    t1 , t2=?
      

  18.   

    t1 =="lucky"
    t2 =="lucky2"temp1==nulltemp2==null局部变量退出作用域后全局变量的值是其拷贝
    t1,t2得到局部变量的副本.
      

  19.   

    js使用cookie实现session功能,事实上asp的session本质上仍旧使用的是cookie。我想在js中带来效率低下的主要原因是你使用了大量的循环,不适当的深层次遍历数组,以及setTimeout等频繁调用。如果你尽量少使用滤镜,不会损失太多效率。
      

  20.   

    回复人: Dickensi(流星·逐日)(★★★★) (  ) 信誉:98  2002-09-12 12:53:00  得分:0  
     
     
      to qiushuiwuhen(秋水无恨):
    是的!
    不过了解一下这方面的内容!
    可能代码效率会高些!这里还后点疑问:
    大家看看
    ////////////////////////////////////////////////////////////////////
    ///
    <script>
    var t1 = null;
    var t2 = null;function test(){
      var temp1 = "lucky";
      var temp2 = new String("lucky2");
      t1 = temp;
      t2 = temp2;
    }
    </script>
    ///
    ////////////////////////////////////////////////////////////////////猜猜看!test结束后temp1,temp2会不会释放?
    t1 , t2=?
      
     
    ===========================================
    晕,你到底明不明白前人所说的,多看书!
      

  21.   

    你能保证t1,t2是副本?有没有相关的资料!我的看法是:temp1,2分配的内存根本没释放!我想ie应该有一个类似于虚拟机之类的东西,用来解释js,调用com,java...
    其拥有自己独立的地址空间!其内存都是在heap分配的!但该虚拟机可以自动地管理这些内存的!可能上面用string举例不是很恰当,java中的String 也是个很特别的对象!
      

  22.   

    无论你用什么开发,(我的java学得不好)但是你都应该学习数据结构,软件工程,编译原理。否则什么都学不好。
    个人看法,毛主席教导我们:“好好学习,天天象上”到此为止!祝你好运!
      

  23.   

    llrock(百乐宝):
    老兄,你看仔细了那段代码,好不好!它的实质跟前面的代码是完全不一样的!我没有用任何setTime(),
    只是我的代码中使用了很多xml,
    了解内存管理后我就能很方便的去释放那些不用的xml所占用的内存了!js实现session功能,与jsp,asp的session本质是完全不一样的。
    虽然都用到了cookie,但是js是存在本地内存(ie空间),session是存在服务器内存上!(这里不讨论硬盘存储)这也是我为什么在这里提到js实现类似session功能的原因!
      

  24.   

    session本质上仍然需要本地cookie支持..
    内存的分配是由解释程序代为分配的,但,同样也是由它负责释放,这难道会有什么不对吗..
    要清楚一点的是,使用XML的话,XML解析器也有自己的内存管理(它作为一个COM对象暴露在脚本上下文中),
      

  25.   

    <script>
    var t1 = null;
    var t2 = null;function test(){
      var temp1 = "lucky";
      var temp2 = new String("lucky2");
      t1 = temp;
      t2 = temp2;
    }
    </script>这段代码:你把局部变量的值复制给了全局变量,局部变量早已释放。
    一个没有人知道其指针(地址)的变量时没有意义的(等同于释放),即使她不等于null.
    给你初一道题(用来理解内存分配):
    main(){
      addr();
      loop();
    }
    long *p;
    loop(){
      long i,j;
      j=0;
      FOR(i=0;i<10;i++){
        printf("*p=%1d\n,j=%1d\n",*p,j);
        (*p)--;
        j--;
      }
    }
    addr(){
       long x;
       x=0;
       p=7x;
    }
    实际上这段代码永远都不会停止,自己想想为什么,想通了就知道释放的道理了;
      

  26.   

    提到session,不知道你对缓冲机制有什么理解,总不至于服务器的硬盘和内存一样大小,大胆使用你的session吧,只是小新你的组件就可以了,不正确的使用组件才是导致性能下降的主要因素
      

  27.   

    我想应该是这样的吧!
    SESSION使用COOKIE的本质是在COOKIE中存了一个ID,
    然后根据这个唯一id去map 内存中的数据! 我现在要的就是怎样操作才能强制虚拟机去回收内存?
    是这样么? 用com的话会有森么不同?
    var tt = new Object();
    tt = null;var comobj = ActiveXObject("..comid.");
    comobj = null;各位多谢了!
      

  28.   

    javascript应该和java的垃圾回收机制一样吧呵呵,瞎猜的
      

  29.   

    服务器不是我们讨论的范围!
    我们只讨论客户端IE!我不是说asp,jsp中的session,而是在客户端ie用js模拟session!to llrock(百乐宝):多谢,我后面举的那个js函数,主要是为了说明:
    ////////////////////////////////////////////////////////////////////
    var t1 = null;
    var t2 = null;
    var date = null;
    function test(){
      var temp1 = "lucky";
      var temp2 = new String("lucky2");
      var d = new Date();
      date = d;
      t1 = temp;
      t2 = temp2;
    }
    ////////////////////////////////////////////////////////在test中(现在还没搞清楚它到底是在stack还是heap中分配的),分配的内存
    ,让一个全局变量(也还没搞清楚它到底是在stack还是heap中分配的),引用后会出现什么效果!这里可能用string是不太合适!所以我现在加了一个Date Object, Date绝对不是传的副本!而是引用!test结束后,假如变量在stack分配,则全局变量date将会引用释放了的内存,
    否则,若date有数据...就说明是在heap上分配的了!
      

  30.   

    var tt = new Object();
    tt = null;var comobj = ActiveXObject("..comid.");
    comobj = null;
    以上两者的不同点是:
    前者获得的是一个标准的内部JS对象接口.
    而后者得到的是一个确定的ACTIVE 接口Object实现的接口只在脚本上下文中可访问,在编译语言里使用就要通过某种形式的代理了.
      

  31.   

    Date绝对不是传的副本!而是引用!
    你是根据什么来判断的???
      

  32.   

    这里涉及到的是COM对象接口的问题了(实际上SCRIPT中的对象应该说是一种聚合对象).
    传递的是接口的指针(的副本,接口增加引用计数),
    原指针在退出作用域后减少接口引用计数.
    而实质上对象的内存并没有释放..释放的只是指针变量所使用的那部分内存而已.
    当所有对象接口引用释放后,对象内存被释放..建议你去看看ATL..
      

  33.   

    测试代码:
    var data = null;function displayList(){
    dd = new Date();
    alert(dd.toString());
    date = dd;
    date.setYear(2009);
    alert(date.toString());
    alert(dd.toString());
    }
      

  34.   

    你说的这个想要说明什么???想要说明是在heap中分配还是在stack中分配吗??其实想要对这个追根究底是没有意义的..
    因为变量得到的和分配的仅仅是一个对象的指针而已.
    实质的内存分配有COM去支持..
    但要知道的是,变量按照不同的实现方式可能在堆中分配,可能在栈中分配.
      

  35.   

    有意义的!假如虚拟机不去释放,我要强制它去释放内存!com内部的内存管理是由com去干!但管理com的生命期就应该在虚拟机的事了吧!
      

  36.   

    那是当然.. 
    分配了对象记得释放当然是个好习惯.
    但是在上面的代码中并没有明显的好处.因为在那儿你释放的仅仅是一个指针变量变的内存而已.
    (其实COM的内存确实是在调用进程heap中分配的.)
      

  37.   

    说错了,进程内compoent的内存确实是在调用进程heap中分配的
      

  38.   

    问题是js中的Data 对象好像也不是在栈上分配的!我现在在怀疑是不是object都不在栈上分配!并且是传引用的!
      

  39.   

    不是说了吗.
    作为对象的实体是在heap中分配的.COM管理其生命期.
      

  40.   

    1、js中对象使用的是基于原型的模式(关于设计模式的书中有详细解释,protoType),你说的那个Date只是date对象的一个副本,并非直接引用原有date对象。2、那个全局的范围你搞清楚了吗?叫你一声大哥好吗?真那你没有办法,C中程序从main()开始(请你不要问main的主调函数是谁好吗?),那么我想js把这些细节隐藏起来了,你没有搞清楚再谁的栈中。3、在js中尼不可以你的组件对象在堆中创建,但是它的引用被存贮到了栈中,当被调函数结束,于是被调函数涉及到的变量从栈中一次退出,显然这时js无法在访问你的组件,因为无法知道她是什么样子,所有的空间实质已被释放。补充,你所见到的所有内存事实上是由ie来管理的,ie负责存储管理工作,至于ie采用什么方式进行存储保护我不知道(假设采用上下界保护方式),当你在ie中创建组件的实例,ie负责在自己管理的空间分配内存,然后在其有效期进行存储保护。例如,你的作业大小为C5F H字节,从内存3A6 H字节处开始装载,当作业的相应进程在CPU中运行时,存储保护的上界是3A6 H,下界的值就是E15 H,在你的对象有效期ie不会对她进行覆盖,当这个对象的引用被销毁时,也就是你举的例子test()结束时,如果没有把temp2拷贝到t2,那么上面那段空间失去保护,你可以在这段空间创建其他的对象;但是你把temp2拷贝到t2,由于全局变量再整个ie生存期有意义,于是ie仍旧保护这段空间,如果你这样做t2=null;那么ie在创建新的对象时检查到没有人在使用这段空间,于是ie可以在3A6 H到E15 H重新使用。也就是说,你根本没有必要手动调用最间的销毁方法,就算调用了他也不过是手动将其占用的空间初始化,但真正管理这段内存的是ie而不是你的组件实例。如果你手动调用组件的销毁方法,但是此时ie中仍旧存在引用这段空间的变量,那么当你使用这个变量时将会出错,因为你调用组件销毁方法后她的空间被初始化了,但ie人就没有释放这段内存,ie人就认为这段内存有意义,并尝试使用它的数据,虽然全部为00。
    也就是说你根本没有必要去手动销毁组件,这是ie做的事情,当ie检测到在自己管理的空间里没有任何对3A6 H引用的变量,那么它就认为这个空间是自由的,也就是被释放的,我真的不想说了,我觉得我已经从本质上给你讲清楚了。
    ===============================
    结论,你的内存是由当前打开的ie来管理的,而不是你的组件,你的组件只管理它了解的那部分空间,但这对于你来说没有意义,ie对于你来说才有意义。无论你的组件对内存进行了什么操作,最终ie会负责管理这段内存。你明白了吗?无论地球人怎么折腾地球上的资源,甚至火星,最终上帝会把银河系收回或者继续任由人类放纵。*** 以下是废话:首先我的专业是化学,不是计算机(但我认真的学习了大量的计算机基础知识),所以我的解释可能存在极端错误,但只有从最基础的层次来解释内存使用,才能清楚。错误的地方请大家原谅,我不想误人子弟,但我没有更好的解释,你总是刨根问底,这佩服你的精神,我24了,已经没有这种精神了,得过且过吧,生活好艰难,一步一步走,祝所有人好运!
      

  41.   

    呵呵,你根本就没有理解 yonghengdizhen(离散数学(学习中,请勿打扰))的意思,new obj的实体再堆中,但是在参数表中(使用栈机制)存放了他的引用,ok?
      

  42.   

    其实说来说去不如那VC的调试器看看它的汇编码..hoho.new从我对C++的理解上来说是在heap中分配,
    并且我们能看到对应的delete,这和C++中的操作有着惊人的相似.但是在这里我认为,没有及时的delete并不会造成太大的影响,因为在这里所占用的只是一个对象指针的内存而已,更何况还有解释程序自动处理无用内存的收集.所以到这里我都不知道该同意你们哪一个的观点了.