Empty arrays, dictionaries, and sets use singleton storage objects (example), so they don't actually allocate memory. It is marked an immortal object, so reference-counting operations should be extremely cheap for it.
As for small arrays, I guess it just wasn't worth it. String is twice the size of Array (16 bytes vs 8 bytes). I remember there being some debate about this, but it was considered very important and desirable that Array not be any larger than a single pointer (I think the reason might have had something to do with multi-dimensional arrays -- i.e. arrays of arrays).
String is not generic - native strings always contain UTF-8 text, and given the way UTF-8 works, it can actually store a reasonable amount of text in its 16 bytes. Array is generic, and for common types like Array<Int>, it would't even be able to store a single element.