Хороший, интересный вопрос! Я не помню, чтобы это было где-то в одном месте, но можно обратиться к документации:
https://spark.apache.org/docs/latest/rdd-programming-guide.htmlИли к сторонним источниками, например сюда (тут очень кратко):
https://www.waitingforcode.com/apache-spark/data-representation-in-spark-rdd/readКак я себе сейчас это представляю, RDD всегда параметризован типом T: ClassTag, который может быть практически любым. Как правило, если работа идёт с датафреймами, можно прозрачно получить RDD[Row], но у него имеется внутреннее представление, RDD[InternalRow], которое быстрее, так как работает с сериализованными данными. InternalRow реализуется в разных классах:
https://www.waitingforcode.com/apache-spark-sql/generated-code-spark-sql/readИз этой статьи видно, что String, например, может быть представлен и в виде raw memory (unsafe projection) и как ссылка на Object (safe projection). Оба эти представления располагаются в heap, если не включен off-heap.
Если возвращается (ArrayList<T>) list.iterator, по-моему, будет получен RDD<T>, но если возвращается сам list, то будет RDD<ArrayList<?>>, тип списка будет стёрт, но RDD сохранит TypeTag и всё равно будет знать, что там конкретный тип
Применяется ли copy, не могу сказать точно, но ни разу не видел в коде вызова этого метода для java Object. Может не туда смотрел. UnsafeRow.copy используется очень часто, и я применял этот метод много в каких случаях, иначе сохраняются ссылки на одну и ту же область памяти