> This, actually, is one of my favorite points. Letting the JVM grab a giant allocation at startup is fine if all you're going to do with your machine is run JVM programs (i.e. a server), but it sucks when you've got multiple apps all trying to play nice together. The OS has a memory management system for a reason. I'd much prefer my runtime use the existing system, than re-invent the wheel (as it were).

The OS memory management system is as general-purpose as possible. At the kernel/process interaction level, the APIs are thin abstractions on the underlying VM page mapping system. Below that, at the malloc level, malloc is designed to be as general purpose allocator as possible, without introducing complexity unsupportable in C, such as migrating allocations across generations.

The JVM's lack of ability to rededicate pages to the OS is a failing of Sun's particular implementation, and is not strictly inherent in the design of generational collectors.

Your argument dismantles Sun's architectural choice when used on mobile hardware, but does not address the relative merits of alternative allocation/collection schemes.

> In regards to the class registration system: "It seems that perfection is reached not when there is nothing left to add, but when there is nothing left to take away"

That response has little substance. It's not perfect, or even great, it's merely functional. I would be enthralled if Mach-O two-level namespacing worked with ObjC classes, but it can not.

> The type encodings are simple C strings!

They're C strings, not particularly simple. Try decoding (with lackluster documentation) a complex structure return value. Modern runtimes use much more cleanly structured, cross-referenced data here.

> If by that you mean that the central message dispatch routine is hand-optimized assembly for each platform the runtime is available on... I'll have some more of that, please!

No, that's not what I mean. You'd find just as much complex hand-optimized assembly code in other runtimes, likely more.

I'm referring to design choices such as the use of unnecessarily complex data structures with minimal if not outright missing API to access them, poorly abstracted implementation details (such as exposing C string type signatures as the highest-level representation of a type encoding), minimal/missing/poorly-defined metadata.

An example is the failure to encode type data in blockrefs in the first public release of blocks for ObjC, which made it impossible to implement imp_implementationWithBlock(), due to the need to differentiation between stret vs non-stret return types and select the appropriate trampoline. This required changes to both the compiler and the runtime, and meant that prior to those changes' introduction by Apple, it would have been impossible for an external entity to implement similar functionality.

This sort of hackish minimalism is the polar opposite of the careful considered and long-term focused design that Microsoft (and even Sun) applied to the core of their platform. Compare the completeness (and longevity) of the JVM Virtual Machine specification to the ObjC runtime. Over roughly the same amount of time, Apple has had to introduce complete ABI-breaking fundamental changes of to their runtime to implement extremely basic language enhancements. In contract, the JVM specification has not, to my recollection, been broken once over the course of 20 years. Additions have always been forward-compatible.

An example of the above would be the addition of non-fragile base classes through the use of minimal ivar access indirection. This required a wholesale breakage of the entire language, and thus could only be introduced on 64-bit Mac OS X and on iOS.

Apple's language and runtime design is hackish at best.