为什么调用Recycle()方法对每个Java对象很重要?
2010-11-30 17:41
330 查看
当你想要直接在本地访问同一个服务器的Lotus Notes® objects信息时,你可以用Java的代理(agent),小服务程序(servlet),小应用程序(applet)或者独立的应用程序来进行。
小应用程序[applet]通过模拟LotusScript对象模型,使开发人员更简单使用这些工具。例如,通过使用LotusScript或者Java类来得到一个数据库的句柄,以及包含数据库信息的会话(session)。一旦会话(session)被创建,你就可以通过这个会话(session)来引用相应的数据库(database)。
然而,为了实现最佳的系统性能,回收创建过的对象是非常重要的。对于LotusScript对象或者其他的Java对象。什么时候是调用方法Recycle()的最佳时机呢?
解答:
使用LotusScript来创建对象
当使用LotusScript来创建一个对象的时候,实际上你创建的是两个对象:一个在LotusScript,一个在Notes后台(C++code)对象。LotusScript只是指向C++对象,而真正实现类的行为的是C++。当LotusScript的代理(agent)或事件(event)结束后,这两个对象将自动撤销。如果对象没有消除,他们将继续保存在内存里,从而造成内存泄漏。
使用Java创建对象
如果你用Java创建一个对象,同样是这样的。Java对象是一个指针,指向用C++创建的对象。这在纯Java代码里是很常见的,通过把一些变量设置为空,使垃圾回收能够立即执行。这种机制被称为积极的垃圾回收。
然而,当Java使用notes对象时把相关的变量设置为空,用来标记需要垃圾回收,而对应的C++对象并不做任何处理。那垃圾回收就只会作用于Java对象,而不会影响C++对象。
为什么要回收?
Recycle()在回收C++对象的同时把Java对象设置为可垃圾回收的状态。如果你只是标记对象为空,你依旧会遇到内存问题。当你在代理中用对象,当代理结束时,所有的对象(无论是Java还是C++)都会被回收。当使用Java服务器程序(Servlet),.jsp 或者独立的应用程序的时候,Recycle()方法必须要被使用,因为Domino自己是不能清除这些后台对象的。
相反,如果一个对象设置为可回收的,它将不会被置为空(Null)。从理论上说,你仍旧可以引用这个对象,并且不会发生灾难性错误,只不过要抛出异常(exception)。当多个引用来调用同一个的对象,这一点是很重要的,例如:“db = mydb.nsf” 和 “db = yourdb.nsf” 同时使用。因为这样非常混乱,并且得到的结果也不可靠。
明白什么样的对象将被创建,将如何设置,以及什么时候使用是很重要的。对象是一个层次的结构。例如,回收一个父文档对象,相应的也就回收了它所有的子对象。因为会话(session)对象在整个对象层次的最上层,所以,回收一个会话(session)对象的时候,同时也回收了放在这个会话(session)对象中所有其他的对象。
查询对象:
在Domino Designer进入设计面板,点击代码区域,查询“回收(recycle)”或者任何你想要查询的对象。并设置查询的范围为当前对象或者所有对象。
如果没有查找到任何Recycle()方法,你可以找一个开发人员来看一下,并在所有的对象使用完后加上一些代码来回收它们。有一点需要注意,在一个循环里使用new 来实例化一个类时,每执行一次循环,一个新的object就会被创建,除非你在循环体里回收这个object,否则object将一直驻留在内存里。
注意:
下面代码是个脚本例子,提供了处理这个问题方法的说明。你可以使用这个脚本,但是要自己承担风险。以执行为目的使这个例子,脚本必须明确规定了如下所示。产品支持无法自定义此脚本的具体环境或应用程序。
循环使用Recycle()和积极垃圾回收的例子:
小应用程序[applet]通过模拟LotusScript对象模型,使开发人员更简单使用这些工具。例如,通过使用LotusScript或者Java类来得到一个数据库的句柄,以及包含数据库信息的会话(session)。一旦会话(session)被创建,你就可以通过这个会话(session)来引用相应的数据库(database)。
然而,为了实现最佳的系统性能,回收创建过的对象是非常重要的。对于LotusScript对象或者其他的Java对象。什么时候是调用方法Recycle()的最佳时机呢?
解答:
使用LotusScript来创建对象
当使用LotusScript来创建一个对象的时候,实际上你创建的是两个对象:一个在LotusScript,一个在Notes后台(C++code)对象。LotusScript只是指向C++对象,而真正实现类的行为的是C++。当LotusScript的代理(agent)或事件(event)结束后,这两个对象将自动撤销。如果对象没有消除,他们将继续保存在内存里,从而造成内存泄漏。
使用Java创建对象
如果你用Java创建一个对象,同样是这样的。Java对象是一个指针,指向用C++创建的对象。这在纯Java代码里是很常见的,通过把一些变量设置为空,使垃圾回收能够立即执行。这种机制被称为积极的垃圾回收。
然而,当Java使用notes对象时把相关的变量设置为空,用来标记需要垃圾回收,而对应的C++对象并不做任何处理。那垃圾回收就只会作用于Java对象,而不会影响C++对象。
为什么要回收?
Recycle()在回收C++对象的同时把Java对象设置为可垃圾回收的状态。如果你只是标记对象为空,你依旧会遇到内存问题。当你在代理中用对象,当代理结束时,所有的对象(无论是Java还是C++)都会被回收。当使用Java服务器程序(Servlet),.jsp 或者独立的应用程序的时候,Recycle()方法必须要被使用,因为Domino自己是不能清除这些后台对象的。
相反,如果一个对象设置为可回收的,它将不会被置为空(Null)。从理论上说,你仍旧可以引用这个对象,并且不会发生灾难性错误,只不过要抛出异常(exception)。当多个引用来调用同一个的对象,这一点是很重要的,例如:“db = mydb.nsf” 和 “db = yourdb.nsf” 同时使用。因为这样非常混乱,并且得到的结果也不可靠。
明白什么样的对象将被创建,将如何设置,以及什么时候使用是很重要的。对象是一个层次的结构。例如,回收一个父文档对象,相应的也就回收了它所有的子对象。因为会话(session)对象在整个对象层次的最上层,所以,回收一个会话(session)对象的时候,同时也回收了放在这个会话(session)对象中所有其他的对象。
查询对象:
在Domino Designer进入设计面板,点击代码区域,查询“回收(recycle)”或者任何你想要查询的对象。并设置查询的范围为当前对象或者所有对象。
如果没有查找到任何Recycle()方法,你可以找一个开发人员来看一下,并在所有的对象使用完后加上一些代码来回收它们。有一点需要注意,在一个循环里使用new 来实例化一个类时,每执行一次循环,一个新的object就会被创建,除非你在循环体里回收这个object,否则object将一直驻留在内存里。
注意:
下面代码是个脚本例子,提供了处理这个问题方法的说明。你可以使用这个脚本,但是要自己承担风险。以执行为目的使这个例子,脚本必须明确规定了如下所示。产品支持无法自定义此脚本的具体环境或应用程序。
循环使用Recycle()和积极垃圾回收的例子:
import lotus.domino.*; public class JavaAgent extends AgentBase { public void NotesMain() { try { Session session = getSession(); AgentContext agentContext = session.getAgentContext(); Database db = agentContext.getCurrentDatabase(); View v = db.getView("SomeView"); // turn off auto-update so that if we make a change to a document // and resave, it won't affect the sort order in the view v.setAutoUpdate(false); Document doc = v.getFirstDocument(); Document temp = null; //sets the temp for garbage collection immediately while (doc != null) { // do something with the document here... // whatever, just don't delete it (yet)! temp = v.getNextDocument(doc); // get the next one doc.recycle(); // recycle the one we're done with doc = temp; } // end while } catch(Exception e) { e.printStackTrace(); } } }
相关文章推荐
- 为什么调用Recycle()方法对每个Java对象很重要?
- Java中为什么匿名对象中方法,调用局部变量必须加final呢?
- 为什么Java的每个对象都有wait()/notify()方法?
- java在调用System.out.println()打印一个新new的对象时,为什么会调用toString方法?
- java在调用System.out.println()打印一个新new的对象时,为什么会调用toString方法?
- JAVA本地方法调用(3)对象参数传递
- 为什么java的子类中必须调用父类的构造方法
- Java父类对象调用子类实体:方法重写与动态调用
- Java反射:通过父类对象调用子类方法
- java创建一个子类对象是会调用父类的构造方法会不会创建父类
- 为什么不使用工厂模式,以new Class的方式实例化对象并调用方法不利于项目升级的维护
- java反射调用某个对象的方法
- 今天发现c#中的实例后的对象是不能调用静态方法,以前学Java的时候是可以的.
- Java对象初始化步骤&&子类继承父类后变量与方法调用情况
- 用jni API 访问java对象的属性,方法,调用构造器
- 【java】子类可以通过调用父类的public方法调用父类的private方法,为什么?
- JNI调用java方法, new java对象,new java内部类
- 安卓利用kotlin的变长参数与伴生对象写出java可以调用的静态方法
- 两种php调用Java对象的方法
- 用JAVA语言编写程序:包含两个类,一个类Cricle中包含计算圆周长,面积的方法。在另一个类Compute中给出半径值为10,创建对象,并调用Cricle类中的方法,计算该对象的面积、周长并显示出结