On Wed, Jul 11, 2012 at 4:38 PM, Andreas Rossberg <[email protected]>wrote:
> In any case, before you conclude that finalization is the answer to your > problems, let me +1 Sven's recommendation on reading Boehm's paper on the > subject. Finalization is pretty much an anti-pattern. There are some rare, > low-level use cases, but usually it creates more problems than it solves. > That's why we only provide it in the C++ API. > Just to beat a long-dead horse for a moment... Quoting Boem's paper: Page 1: "We argue that although finalization is rarely needed, it is often critical when it is needed. In these cases, its absence would render the garbage collector useless." "Rarely needed" is, in my (not inconsiderable) experience, 100% wrong for JS bindings. The vast majority of the interesting client-side NATIVE types which we want to bind to JS require resource acquisition and a large percentage of them require well-defined finalization/destruction in order to guaranty proper behaviour. Examples, just off the top of my head: - File handles must be close()d in order to ensure that they are flushed. Yes, the OS closes them when the process exit()s, but AFAIK they are not automatically flush()ed. - Database drivers, statement handles, and query cursors all have very specific cleanup requirements, and failing to properly close() a db handle "could" (though admittedly "shouldn't") lead to undefined behaviour e.g. db corruption. - Anything which heavily relies on parent/child relationships, UI toolkits being a prime example. Getting those working properly in JS can be a real PITA because the child/parent relationships must be tracked in both JS and native space in order to keep all the objects around for their proper lifetimes. (When i first implements an ncurses binding for JS i quickly found i had to make JS aware of all child window references to keep them from being GC'd out from under the parent window's nose.) We (client-side users of scripting engines) don't bind trivial classes to native implementations. Such impls are done in JS because it's 100x times easier to do so (e.g. the canonical "Point" class example). When we bind natives its because we need native functionality which we cannot get at from JS, and the vast majority of such functionality requires access to "interesting" native resources with arbitrarily complex compositions and cleanup requirements. i don't know of a single commonly-used C/C++ library which does _not_ require that clients clean up resources it asked the library to allocate for them. Section 3.3, bullet point #1: "There is usually not much of a point in writing a finalizer that touched only the object being finalized, since such object updates wouldn't normally be observable." i understand that this assertion "can be true", but it assumes that the statement from Page 1 is true, which it is absolutely not for the generic case when binding native C/C++ types to JS. To be clear: i'm not picking no v8 here. In time since i wrote the original gripes which Michael S. linked to in the top post of this thread, i have since come to understand much more about the difficulties of finalization ordering and whatnot, and have a much deeper appreciation for the nature of the problem. Nonetheless, assertions like Boem's quotes above, in my opinion, simply hand-wave away a _majority_ of use cases as "not useful" or "rarely seen," when in fact the problem is that they are just damned difficult to solve. Obviously Boem is the top of his field, and i don't discount his brilliance in this subject matter, but hand-waving away such problems as being "infrequent" does him no credit. -- ----- stephan beal http://wanderinghorse.net/home/stephan/ http://gplus.to/sgbeal -- v8-users mailing list [email protected] http://groups.google.com/group/v8-users
