Recientemente vi uno de esos videos que comparan Android contra iPhone, y lo mejor es que lo hacía un conocido hater de Apple. Un tipo que dedica medio canal a criticar a la manzanita… y aun así terminaba concediendo puntos donde Apple le ganaba a Android. El más grande: desde sus orígenes, Apple ha usado menos RAM y menos recursos que Android.

Lo que el video no hacía era explicar el porqué. Y ahí me quedé yo con la pregunta: ¿cómo un teléfono con la mitad de memoria rinde igual que su competencia?

Este artículo es esa explicación en contexto rápido: por qué en un origen Apple tenía una ventaja técnica sobre Android.

Ahorita llegamos, pero primero una incomodidad: ya no es 2020. El iPhone 17 Pro ya trae 12GB, el Galaxy S26 subió a 12-16GB, y en su punto máximo la diferencia entre ambos bandos fue de 10GB (PhoneArena). El subtítulo de este artículo se pone honesto: O al menos solía ser.

La diferencia siempre fue el lenguaje

Cuando salieron los primeros teléfonos con tienda de apps, las dos plataformas se escribían con lenguajes muy distintos: Android con Java, iOS con Objective-C. Ojo: los kernels están en C de ambos lados, pero el sistema operativo, las apps y —sobre todo— cómo se gestiona la memoria vivían en mundos opuestos.

De un lado, Java: comodidad total para el programador. Del otro, Objective-C: C con esteroides, o como dicen algunos, C con sabor a objetos. Y de esa diferencia nacen las dos filosofías de memoria de este artículo.

El precio de dormir tranquilo

En todo programa hay que hacer algo básico: alojar memoria para una variable y liberarla cuando ya no sirve. Java hizo eso transparente con la recolección de basura o garbage collection: una rutina que corre junto a la aplicación y va buscando referencias a memoria que ya nadie usa, para que un algoritmo determine qué liberar y qué no.

Aclaración: Java no inventó la garbage collection. La inventó John McCarthy alrededor de 1959, para Lisp (Wikipedia). Lo que hizo Java fue traerla al mainstream y convertirla en el precio estándar de programar sin preocuparte por la memoria.

El programador dejó de liberar memoria. Alguien más la libera por él — y paga en tiempo de ejecución.

Diez años de JVM que nadie vio venir

Con ese pequeño disclaimer: el Java de hace 10 años no es el mismo de hoy. La JVM se modernizó en una década que pasó casi desapercibida para el usuario:

  • G1 es el recolector por defecto desde JDK 9 (2017), y ZGC pasó de experimental (JDK 11) a producción (JDK 15) hasta volverse generacional por defecto en JDK 23 (JEP 474).
  • Las virtual threads (JDK 21) cambiaron cómo la JVM maneja la concurrencia (notas de Oracle).
  • En JDK 24 llegó la carga y ligadura de clases ahead-of-time, que reduce el tiempo de arranque, y los encabezados de objeto se achicaron a 64 bits (llegada de Java 24).

Y no olvidemos el otro lado de la moneda: el hardware ha evolucionado tanto que un teléfono de hace 10 años simplemente no tiene las capacidades de hoy. La JVM mejoró, sí, pero también le dieron silicio con el que trabajar.

Apple solo sabía contar referencias

Del lado de iPhone, la historia arranca en otra empresa: Apple heredó Objective-C de NeXT, la compañía de Steve Jobs, cuando la compró a fines de los noventa (Wikipedia).

Originalmente, Objective-C recomendaba a los desarrolladores liberar las variables a mano: retain, release, autorelease. Luego los ingenieros de Apple se dieron cuenta de algo predecible: los programadores seguimos siendo descuidados. Olvidamos liberar, o liberamos por error algo que aún se usaba.

La respuesta fue ARC —Automatic Reference Counting— presentado en el WWDC 2011 con Xcode 4.2 e iOS 5 (notas de Apple). Qué hace: en tiempo de compilación cuenta las referencias de una variable, las resta cuando dejan de ser útiles y, cuando el contador llega a cero, el compilador inserta la llamada que libera la memoria. Su punto ciego son los ciclos —dos objetos que se referencian entre sí nunca llegan a cero— por eso existen las referencias weak.

Una vez compilada la aplicación, no hay ninguna subrutina corriendo en paralelo buscando basura: las cuentas ya están hechas. Y sí estaba por defecto en el sistema operativo y en las aplicaciones.

No hay un demonio corriendo en segundo plano. Hay un compilador que ya hizo las matemáticas.

Swift: casi, pero sin prisa

Swift se anunció el 2 de junio de 2014 en el WWDC (TechCrunch). Heredó muchos patrones de diseño de Objective-C, y la idea de Apple era clara: atraer más desarrolladores al ecosistema con un lenguaje más amigable, lo suficientemente poderoso como para sustituir a Objective-C en bajo nivel y en alto nivel. Hoy eso está casi completado.

Eso no salió gratis. De buenas fuentes he escuchado algo que comparto: Xcode tiene muchos problemas con cada versión, porque con el paso de los años Swift se ha vuelto más complejo, y la herramienta con él. No estoy solo: en el WWDC 2026, Apple reconoció el peso y respondió con Xcode 27, 30% más ligero y exclusivo de Apple Silicon (State of the Union).

Pero la visión original sobrevive: optimizar en tiempo de compilación. Swift 6 trajo seguridad en concurrencia, y la versión 6.4 ya está disponible con mejoras ergonómicas y un Foundation más rápido (qué hay de nuevo).

Y aquí el giro bonito: hasta en Android hay experimentos corriendo Swift hoy (swift.org). El lenguaje que Apple crió de su lado de la cerca hoy coquetea con el lado de Java.

Android también aprendió a compilar

Y aquí es donde se responde la pregunta del inicio: ¿hoy quién optimiza mejor la RAM?

Android ya no corre Java en una JVM como tal. Desde Android 5 (2014) reemplazó Dalvik por ART, que compila de forma anticipada; desde Android 7 (2016) mezcla AOT, JIT e interpretación con perfiles de uso, y Google Play manda perfiles en la nube para pre-compilar lo que cada usuario realmente usa (cómo funciona ART). Esas Baseline Profiles aceleran el primer arranque alrededor de 30% (Android Developers), y desde 2019 Android es Kotlin-first (Android Developers).

En memoria también se emparejaron: iOS comprime páginas y expulsa apps con jetsam; Android hace lo propio con zRAM desde KitKat (comparativa, documentación de Android).

Entonces, el veredicto honesto: la ventaja fue real y se cerró. Android llegó con un runtime muy capaz de compilar a tiempo, y Apple, que por años vivió con la mitad de memoria de sus rivales, hoy ya pone 12GB — porque hasta la inteligencia artificial en el dispositivo la exige.

Lo que sí sobrevivió de la ventaja

No todo se cerró. La CPU sigue hablando claro: el A20 Pro del iPhone 18 le saca cerca de 30% en single-core al Snapdragon 8 Elite Gen 5 (Beebom).

Y queda la otra ventaja de fondo: el mismo lenguaje y los mismos frameworks en todas las plataformas. Swift y SwiftUI corren en iOS, iPadOS y macOS; adaptar la interfaz entre plataformas sigue siendo complicado, pero en el fondo el core de la aplicación se optimiza una vez y sirve para todos los dispositivos. Apple ya está escribiendo partes del kernel del sistema en Swift (WWDC26).

Android ya compila como Apple, y Apple ya pone 12GB como Android. La ventaja en RAM se cerró.

Porque iPhone optimizaba mejor la RAM que Android. O al menos, solía ser.