[Json-rpc-java] Clientside memory issues with the JSON RPC JavaScript
Arthur Blake
arthur.blake at gmail.com
Tue Oct 30 03:38:51 SGT 2007
Hi Eric.
Just a few quick notes.
1. Synchronous calls have been deprecated and we don't recommend using them
at all anymore. See http://code.google.com/p/jabsorb/issues/detail?id=25
2. We've done quite a bit of refactoring of jsonrpc.js. If you don't mind
examining the latest version to see if you see these same issues, we'd
appreciate it. I will do the same when I have time. If the issues still
exist, we'll create bug tracker entries for them and address them as soon as
possible.
(see http://jabsorb.googlecode.com/svn/trunk/webapps/jsonrpc/jsonrpc.js for
latest version of the code.)
3. I agree that jsonrpc.js is a mess, and I think it needs a total
overhaul... we'll be working on that in upcoming jabsorb releases.
See http://code.google.com/p/jabsorb/ for the latest release of jabsorb,
(formerly known as json-rpc-java.)
On 10/29/07, Eric Pascarello <alienfrog at gmail.com> wrote:
>
> Hello everyone,
>
> I have been working on memory issues with an application and I found some
> major issues within the core javascript of the JSON RPC. There are two
> bugs
> I have found so far and there are other improvements that can take place.
> With this thread I will only talk about the memory issues.
>
> The bugs:
> 1) The object JSONRpcClient.async_inflight is growing with sychronous
> requests.
> 2) There is a circular reference within all of the Ajax calls.
>
> For the JSONRpcClient.async_inflight, who ever coded it forgot to remove
> the
> current request from the object for synchronous requests. The code
> properly
> removes itt for asychronous requests. You can see that by looking at the
> code within the onreadystatechnage callback.
>
> To test for this bug, fire off a series of Synch requests and with Firebug
> console [http://www.getFirebug.com], type JSONRpcClient.async_inflightinto
> the command line. Doing this will allow you to see what is in the array at
> that given time.
>
> So I changed
>
> if(!req.cb)
> return this._handleResponse(http);
>
> to this
>
> if(!req.cb){
> delete JSONRpcClient.async_inflight[req.requestId];
> return this._handleResponse(http);
> }
>
> and JSONRpcClient.async_inflight is no longer gaining in size. That was an
> easy fix. :)
>
>
> The next issue was a circular reference. If you were to inspect the code,
> and look at the DOM tree, you would see:
>
>
> - System
> - listMethods
> - client
> - System
> - listMethods
> - client
> - To Infinity and beyond
>
> Firebug is a great thing because it lets you inspeact the objects. To test
> for this, you can add the line console.log(this); inside of the
> JSONRpcClient constructor I am [thinking it somewhere around 115-118.]
> Click
> on the Object in the console tab and you can navigate the tree and see the
> circular reference first hand.
>
> The circular reference problem is in the following chunk of code in
> _createMethod():
>
> JSONRpcClient.prototype._createMethod =
> function JSONRpcClient_createMethod(methodName)
> {
> var fn=function()
> {
> var args = [];
> var callback = null;
> for(var i=0;i< arguments.length;i++) args.push(arguments[i]);
> if(typeof args[0] == "function") callback = args.shift();
> var req = fn.client._makeRequest.call(fn.client, fn.methodName,
> args, callback);
> if(callback == null) {
> return fn.client._sendRequest.call(fn.client, req);
> } else {
> JSONRpcClient.async_requests.push(req);
> JSONRpcClient.kick_async();
> return req.requestId ;
> }
> };
> fn.client = this;
> fn.methodName = methodName;
> return fn;
> };
>
> The whole problem relates to this line fn.client = this;. They than use
> fn.client inside the function to be able to reference the make and send
> methods. Storing this is in an another object is usually a very bad thing
> to do. What should have been done is used a local variable and reference
> that. This keeps us from causing the endless loop of it refering to itself
> over and over again. Something like this would do the trick:
>
> JSONRpcClient.prototype._createMethod =
> function JSONRpcClient_createMethod(methodName)
> {
>
> var ref = this;
>
> var fn=function()
> {
> var args = [];
> var callback = null;
> for(var i=0;i<arguments.length;i++) args.push(arguments[i]);
> if(typeof args[0] == "function") callback = args.shift();
> var req = ref._makeRequest.call(ref, fn.methodName,
> args, callback);
> if(callback == null) {
> return ref._sendRequest.call(ref, req);
> } else {
> JSONRpcClient.async_requests.push(req);
> JSONRpcClient.kick_async();
> return req.requestId;
> }
> };
> fn.methodName = methodName;
> return fn;
> };
>
> Now there is no circular reference when you examine it in the Firebug
> console. I used var ref = this; to allow me to reference this. We no
> longer
> have to reference client in this chunk of code.
>
> Hopefully someone out there will update the project with the fixes so they
> can have some of their memory back. In the future we can talk about
> improving the code in some other areas.
>
> Regards,
> Eric Pascarello
> _______________________________________________
> Json-rpc-java mailing list
> Json-rpc-java at oss.metaparadigm.com
> http://oss.metaparadigm.com/mailman/listinfo/json-rpc-java
>
More information about the Json-rpc-java
mailing list