Garbage collection has a performance hit which may not be desirable. You don't really want your network stack to stall from time to time. And OS wouldn't be usable in any mission critical environment.
Array boundaries checking also has a performance hit but I am coming to think it is a necessary evil.
Dealing with strings as char arrays is just absurd. There isn't a significant performance hit to use some string datatype that reduce the opportunity for bugs.
Array bounds checking can often be optimized out. For constructs such as "for x in foo {}" this is trivial. The more general cases require a compiler which can hoist subscript checks out of loops when possible. The compiler has to be allowed to generate checks which fail early; that is, if the loop is going to subscript out of range at iteration 100 and there's no way to exit the loop early, then one check at loop entry is sufficient. This is hard to express to some optimizers.
Array boundaries checking also has a performance hit but I am coming to think it is a necessary evil.
Dealing with strings as char arrays is just absurd. There isn't a significant performance hit to use some string datatype that reduce the opportunity for bugs.