Your Plug-in Ate My Application
A good lot of Apple applications implement either a private or public plug-in architectures, such as iPhoto's export plug-in architecture, or iTunes' Visual plug-in architecture. Of course, Safari implements one as well, which lovely, well known banes of my existence, such as Flash and Java, use...in excess.
I'm certain I got off on the wrong foot with some of the guys in the #webkit channel when, after trying to debug a vicious memory leak in Safari that was eating up almost 1/4 of my fancy smancy iMac's memory (2GB) as well as 2GB of virtual memory (see Figure 1). Ouch. They were all very patient in helping me debug my issue, but in the end it seems basically came down to Flash sucks, Java sucks, so if you visit websites that do any sort of...post-Y2k media, Safari's going to bloat, and how. Of course, this brings me to my point, the ever so elusive "point" that usually lacks from so many of my own rants.

Figure 1
Why the hell do these plug-ins suck?!
Ahem. I've known about the basics in terms of how a plug-in works on Mac OS X, or at least how Apple tells us how to do it, regardless of whether or not they follow their own guidelines. The basic idea, is to implement your own formal or informal protocol that all your dynamically loaded plug-ins should follow. So the question is, how are these plug-ins allowed to suck resources into oblivion? When should a plug-in be allowed to start to take the main application along for a ride? (Normally will consume around 40-60MB of memory on my machine)
I'm not so naive to think that it will be any lightweight task to embed the Sun™ Java™ Virtual Machine inside a web view to allow me to play Yahoo! Pool, or that it will be any easy, or simple task to embed the quantum computing engine needed to display the Flash view that is necessary so I can so vigilantly punch that damned monkey just one more time. But surely there are some guidelines, like Apple's own for dynamically loading code, that should be followed here right? According to Apple's guidelines, there are two main security concerns to address when dynamically loading code, the first one is irrelevant, but the second one is:
- Limit direct access by plug-ins to your application code and data. Do not provide the plug-in with pointers to your application controller objects, application data, or other information that could be accidentally misused or intentionally abused.
While it's hard to tell how much data is traversing the vast expanse between Safari's address space, and the Flash Earth Simulator address space. This is scary, presuming MacromediaAdobe has written the Flash plug-in at least half correctly, that means that in the case of Figure 1, that the Flash plug-in is somehow hemorrhaging at least 350MB of memory in just leakage and bloat. But what kind of plug-in architecture can allow for this?
√(-1)
Unfortunately, until garbage collection comes around, we're kind of up a creek in terms of managed code a la C# and Java in the Mac world. But I still think of plug-in architecture very similar to the operating system architecture. In a monolithic operating system, the OS will manage resources and divide them amonst the processes in userland, and the scheduler will allocate resources according to need or priority. While this setup will most definitely not prevent renegade user processes from leaking memory and eating up more and more of your precious system resources as the CPU cycles tick by, I think a host application, like Safari, should act a bit more vigilant when it comes to plug-ins. In my opinion, there should be a definite divide between what a plug-in can and cannot do. Growing large enough in memory to where the rest of my applications' sizes in memory can't even compare. The fact that the Flash plug-in can leak that bad lends me to believe that it's definitely not following any sort of generic protocol. Keep in mind that Safari is based on KHTML which is largely in C++, so where might the plug-in architecture lie? On the Cocoa (Objective-C) side of things, in the middle (Objective-C++), or purely C++. David Young's post regarding flash leads me to believe that most of the Flash nonsense is in C++, but wait, you can write your own Web Kit plug-ins! Another dead end, these can be in either Cocoa, or older Netscape API plug-ins, which means stock C (Web Kit Plugin Programming Guide) Since it's quite obvious that there's some sloppy programming behind the Flash plug-in, and after consulting David's stack trace, it's almost certain that they're following the old Netscape API, good old stock C (which would explain why it took them an eternity to come out with a half decent intel version of their Mac plug-in). Too bad for us however, regardless of the impending release of Objective-C garbage collection in 10.5 Leopard, nothing can really save you from the wrath of something ilke Flash, which really wants as much in terms of resources as it can hold onto. To demonstrate Flash's bloat, start a flash movie, and then let the window lose focus, watch it slow to ~5 fps, a clever hack by the Flash programmers to prevent background windows with Flash content from sucking all your readily available Folding@home CPU cycles.
This sucks.
Unfortunately it seems that the only way to really regulate how much in terms of resources seems damned near impossible, which would be to implement your own very strict memory management, and CPU management code for plug-ins. As somebody who's spent more time in C# (.NET 1.1 and a bit of .NET 2.0), I'm relatively comfortable with stack introspection, or "reflection" as those Computer Science types call it, which I think is what would be necessary to do what I'd want to do, that or some obscene low level hack to load the plug-in into the Application's already set aside memory for the plug-in, mmap(2) anybody? Double unfortunately for us, Objective-C's reflection calls, given the message-passing system upon which it operates, is weak at best. As a software developer, this really sucks, the end-user is not going to recognize a problem with the Flash plug-in, they're going to recognize a problem with Safari, and thus, in their eyes, this is a problem Apple should address. Take Firefox's rumoured memory suck problems, which they've mostly discounted as poorly coded extensions. Plug-in's gone bad! There's no way for Mozilla to win in this case, not only do they get positive feedback for the bajillion extensions for Firefox, but they also take a hit in the press every time somebody drags out bugs that are caused by extensions on Slashdot, Digg, etc. Talk about suck.
The Springer Final Thought
There really isn't a good solution to the problem, plug-ins are a great way to extend your application's functionality beyond it's current feature set, but it also can mean potential support headaches, and pr hits depending on how talented, or untalented the people that write those plug-ins are. I wish there was some sort of feasible alternative to being at the will of bad plug-ins, but at the time being, there really isn't. There is at least some hope though, in a future far far away, say, September, after WWDC whether or not we'll finally get garbage collection, which would mean that provided the plug-ins are all coded in Cocoa, their memory management will be relatively taken care of. Of course, this might all be wishful thinking, and it won't fix Flash's bloat. A hex on all you at MacromediaAdobe.


