Это полностью зависит от платформы и представительства.
Например, в .NET строка занимает два байта в памяти на кодовую точку UTF-16. Однако суррогатным парам требуются два значения UTF-16 для полного символа Юникода в диапазоне от U + 100000 до U + 10FFFF. Форма в памяти также имеет накладные расходы на длину строки и, возможно, некоторые отступы, а также обычные накладные расходы объекта указателя типа и т. Д.
Теперь, когда вы записываете строку на диск (или в сеть и т. Д.) Из .NET, вы указываете кодировку (большинство классов по умолчанию используют UTF-8). В этот момент размер очень сильно зависит от кодировки. ASCII всегда берет один байт на символ, но очень ограничен (без акцентов и т. Д.); UTF-8 предоставляет полный диапазон Unicode с переменной кодировкой (все символы ASCII представлены одним байтом, но другие занимают больше). UTF-32 всегда использует ровно 4 байта для любого символа Unicode - список можно продолжить.
Как видите, это не простая тема. Чтобы определить, сколько места займет строка, вам нужно указать точно какова ситуация - является ли это объектом в памяти на какой-либо платформе (и если да, то какая платформа - потенциально даже вплоть до параметров реализации и операционной системы), или является ли это необработанной кодированной формой, такой как текстовый файл, и, если да, то какой кодировкой.