Tuesday, December 18th, 2007

Working aroung the instanceof memory leak

Category: JavaScript, Tip

<>p>Gino Cochuyt spent some hours to find the cause of memory leaks in IE when using instanceof.

He found at least 3 Objects that cause the memory leaks:

  • window
  • document
  • element

Just using – if (window instanceof Object) – for example causes a memory leak! that grows by 50 KB per refresh; the reason for this is because these 3 Objects are not really objects in IE (they don’t have a constructor); the same reason why they don’t have the Native Object methods:

  • hasOwnProperty
  • valueOf

where in other Browsers like FF, Opera and Safari … (the ones that i tested!)
a div elemement for example is an instanceof HTMLDivElement – HTMLElement – Node etc..

To prevent these memory leaks:

javascript
< view plain text >
  1. function MyClass(){};
  2.  
  3. function testIt (obj) {
  4.         if (!obj || !obj.hasOwnProperty || !(obj instanceof MyClass)) {...}
  5.         // IE will fail on the second statement if obj == window || document.... so the instanceof statement doesn't get tested!!
  6. };

Posted by Dion Almaer at 2:50 am
21 Comments

+++--
3 rating from 22 votes

21 Comments »

Comments feed TrackBack URI

Can’t Microsoft release a DLL as part of some update that fixes this cr*p?

Comment by AndyB — December 18, 2007

Sad.

Lets compare web developers with car stereo manufacturers. Car stereo manufacturers don’t need to worry that their product may be installed on a car with a crappy defect engine. They don’t provide changes in their stereo to improve or fix the defect car engine. Doesn’t the radio work your crappy car? Tough luck, get a better car.

We web developers need to, at some point, start to ignore defect engines. The company behind the defect engine doesn’t care about fixing it, so why should we?

Comment by Jeria — December 18, 2007

@Sad: “Why should we?”

Because quite a large amount of people keep buying the car with the worth-no-penny engine. And they usually are the ones that don’t bother to and/or are not allowed to have more than one car.

Comment by DiscoNova — December 18, 2007

Could you provide a link to the original post?

(Also, off-topic: why can’t I use a space in my “handle”, and why is the Spam Question still around even when registration is required)

Comment by MarkWubben — December 18, 2007

@DiscoNova: I understand too, that too many people use IE to be ignored. Companies that I work for are still under a IE only policy.

WASP used to provide a “Upgrade your browser” page that you could refer Netscape 4 users to. A similar campaign could be done for Internet Explorer users. A campaign like this could have a certain impact (I don’t expect big companies to follow this) that would be picked up by media.

Comment by Jeria — December 18, 2007

@MarkWubben: there is no original post!
this is just a little post with my findings on this problem:
i googled for hours : but I didn’t find any article that handles this problem.
all memory leaks explained are closures and event handling-
i’m currently writing an article that will explain more about this.
- can’t give you an answer to the off-topic question! :)

Comment by 191279 — December 18, 2007

No, he’s right actually. They wont really give a damn that their browser is crappy, not unless they see some resistance. How long do we have to put up with IE hacks, fixing things that we dont want to?

Comment by web freak — December 18, 2007

Could you post an URL to some test page. Since I have troubles reproducing this problem tested on IE 6 on XP and IE 7 on Vista using a for 0 to 100 loop and with a window instanceOf Object inside and I can’t see any leaks?

Comment by Spocke — December 18, 2007

We don’t manufacture sound systems for cars, we roll out the roads. Good luck getting people to drive on your roads if the average car breaks down on them (think steep climbs or rough bumps).

Comment by Tim Cooijmans — December 18, 2007

Sigh.

While I do appreciate the point of view that because the other browsers handle their DOM in a consistent way WRT to JS handling…it’s well documented (at at least MSDN) that the IE DOM is a COM+ object, and *not* a native JavaScript one. That means that any time you try to treat one of the DOM objects in IE as a JavaScript one, you’re forcing IE (or anything else that you are using JScript for, like Windows Shell or classic ASP) to wrap it with an actual JS object (there’s plenty of docs out there about this, it’s there to handle the whole expando concept), and *this* is where the memory leak comes from.

There’s a simple solution for this: don’t expect DOM objects to be JS ones, and use the interfaces that both the W3C and MS provide for you for access.

You all need to remember that an awful lot of the stuff that MS created is not aimed just at script manipulation but also at other things, such as C++/MFC programming. I’m remembering a valid complaint Scott Andrew once made WRT to XMLHTTP’s readyState, as well as it’s responseStream and responseBody properties…and the reason for his complaint was because he was looking at it from the point of view of a scripter as if *that was the only use MS had for said objects*. It’s not; it was designed to be used by almost anything in the MS ecosphere.

I am certainly not happy either about the state of IE but at the same time simply bashing it because you’re doing something that has implications outside of the scripting environment doesn’t help either.

Comment by Tom Trenka — December 18, 2007

@Tom Trenka: Yes, the object element is another case where it looks like a DOM element but it’s actually an ActiveX instance so some DOM methods doesn’t work the same way on that instance. I think that’s a bigger problem than the fact that the window, document objects isn’t real JS objects since it produces issues when trying to serialize the DOM tree on IE.

But anyway, I think it’s an bad idea to expose the C/C++ APIs directly at a script level they should have wrapped it better so that everything works as expected at the JS level.

Comment by Spocke — December 18, 2007

But anyway, I think it’s an bad idea to expose the C/C++ APIs directly at a script level they should have wrapped it better so that everything works as expected at the JS level.

You demonstrate my point: we can’t just be looking at this from the point of the scripter =) Seriously though, one other thing you should probably remember is that most of these APIs were devised a long time ago (late 90′s, IIRC); the big complaint here shouldn’t be that you get unexpected results when scripting, but why does MS hold onto that model. And your answer probably revolves around the desire on the part of MS to be able to include and/or embed mshtml as a control in, say, a Windows Form app. There are a lot of cross-purposes going on here, and to just assume that the scripter is all important, while understandable, is just that–and assumption.

Comment by Tom Trenka — December 18, 2007

@Tom Trenka: The thing is that I think that the MS folks have reused to much of these components the end result was an insecure browser environment a good example was older version of Outlook that used the IE ActiveX control for it’s HTML presentation, the result was that any script inside the attached HTML mail body would have full access to the windows API by simply creating new object instances using createObject. I remember viruses and Trojans exploiting this ability all the time that was one of the main reasons I never use Outlook anymore even if they fixed it.

So I agree with you the main problem is that the M$ folks used an to direct approach in the first place they should have wrapped and separated everything nicely from the start I think they got carried away when they designed the IE, like “Wow we can now talk to DirectX and do a 3D cube!!” but what about the security and scripting issues.

Comment by Spocke — December 18, 2007

@Spocke: I don’t disagree with you at all with what you’re saying; I’m just saying that to blame MS for a memory leak when you don’t have a full or moderate understanding of how their DOM model works is a bad thing, and that it’s really easy to hop on the “bash IE” bandwagon when some of it is really our fault.

Comment by Tom Trenka — December 18, 2007

Yeah, stupid JavaScript developer using the instanceof operator on an object that is actually a COM+ object. He should really feel that it is his fault the browser leaks, since he does not really understand the entire architechture behind COM+ objects.

Comment by Jeria — December 18, 2007

@Tom Trenka: Yes, I haven’t even been able to reproduce this memory leak. And some times I think the leaks are produced by third party addons instead of IE so the poor browser gets blamed for something it didn’t do. I’m not on the “bash IE” bandwagon actually I have had far less problems with IE when creating TinyMCE than other so called W3C compatible browsers, the things IE supports is pretty much rock solid compared to other some other browsers the only problems are some memory leaks and the lack of support for modern specs. I hope IE 8 will be a step up on those two and that they separate the COM+ objects from the DOM. :)

Comment by Spocke — December 18, 2007

@Spocke: I hope so too, but based on past history I’m not holding my breath.

Comment by Tom Trenka — December 18, 2007

Yeah, stupid JavaScript developer using the instanceof operator on an object that is actually a COM+ object.

@Jeria: By the way IE only supports “JScript” and not “JavaScript”.

Comment by Jordan — December 19, 2007

I’m glad other people look into this kind of stuff. I have nearly no clue to 80% of the causes of memory leaks except for the classic circular references to DOM nodes and their respective event listeners.

I’ll keep my distance and focus on the language itself. But this is still great news to keep up with.

Comment by ded — December 19, 2007

Tom Trenka wrote:I’m just saying that to blame MS for a memory leak when you don’t have a full or moderate understanding of how their DOM model works is a bad thing, and that it’s really easy to hop on the “bash IE” bandwagon when some of it is really our fault.

This is a misunderstanding of the nature of abstractions.

The object IS a Javascript object, it is just implemented as a COM+ object. What it is implemented should be no concern of the programmer using the API – it is an implementation detail. When the API does not follow the (implied) spec (it leaks), then that is a bug in the API implementation, and whatever is underneath that API is completely irrelevant for this. The abstraction is the API – that’s where responsibility is handed over.

It is like file writing – when I write data to a file, I don’t care what filesystem it uses. If one particular operating system started bugging out when it saw files containing 0xff3465abf because they were using it as a magic on-disk marker, we would rightly blame the operating system, no matter how convenient it was for them to use this magic marker in their on-disk layout.

In the same way I am reasonably going to see these memory leaks as MS’ fault, no matter how convenient it is for them to use COM+ objects underneath.

Comment by Eivind Eklund — December 19, 2007

The object IS a Javascript object, it is just implemented as a COM+ object. What it is implemented should be no concern of the programmer using the API – it is an implementation detail.

The spec, as written by Microsoft, just says that window and document are objects. It doesn’t say that they are “JavaScript” object. For all we know they could be Pascal objects or Fortran objects. And from context, we know that they are likely to be COM objects because those APIs were written to be callable in C++. The spec just says how scripts can be used to access those objects and doesn’t define how it should behave in every situation. Therefore not behaving like JavaScript objects is not against any prescribed behavior.

Comment by spam — December 19, 2007

Leave a comment

You must be logged in to post a comment.