[HN Gopher] Transition to using 16 KB page sizes for Android app...
       ___________________________________________________________________
        
       Transition to using 16 KB page sizes for Android apps and games
        
       Author : ingve
       Score  : 89 points
       Date   : 2025-07-11 07:04 UTC (4 days ago)
        
 (HTM) web link (android-developers.googleblog.com)
 (TXT) w3m dump (android-developers.googleblog.com)
        
       | userbinator wrote:
       | Weird. AFAIK 4K and 64K were the common ARM64 page sizes, and 16K
       | was the odd "think different" one that Apple uses. No mention of
       | 16K in the Linux kernel docs:
       | 
       | https://www.kernel.org/doc/html/next/arm64/memory.html
        
         | jeffbee wrote:
         | 16K _is_ the weird one in practice, but ARM says they are
         | implementation-defined.
         | 
         | https://developer.arm.com/documentation/101811/0104/Translat...
        
         | ryao wrote:
         | The 64-bit kernel shipped for the Raspberry Pi 5 uses 16KB
         | pages.
        
         | tux3 wrote:
         | 64K starts to be a little too wasteful. It is a small
         | performance gain as you'd expect, but less granularity means
         | significantly more wasted memory
         | 
         | On a phone with limited RAM, this starts to be a bad tradeoff
         | quickly. 16K is a reasonable jump from the venerable 4K page
         | size.
        
         | fsfod wrote:
         | AMD also switched to 16k(4 x 4K) down from 8 in Zen1 for there
         | PTE Coalescing system that is effectively run length like
         | compression of page table entries with sequential addresses in
         | to one TLB slot.
        
       | nubinetwork wrote:
       | I can understand the desire for google to want devs to recompile
       | their apps, but I don't see the need to dump old apps from the
       | app store... who cares if an old app that works wastes 12k if it
       | only needs a single 4k page?
        
         | ryao wrote:
         | I am not familiar with Android, but Linux ELF binaries that
         | specify 4KB alignment will not work on systems with 16KB page
         | sizes, since the ELF interpreter will refuse to load them. This
         | hit me recently when trying to run a 32-bit binary on a Linux
         | ARM system that had 16KB size pages, since the 32-bit OpenSSL
         | libraries specified 4KB alignment. Presumably, this was done
         | for maximizing entropy available to ASLR, but it breaks the
         | binaries when the page size increases.
         | 
         | In any case, I assume that there is something similar affecting
         | Android.
        
           | dwattttt wrote:
           | Page size impacts page permissions; it's not a matter of
           | wasting 12k, it's that with 4kb pages you're allowed to have
           | a consecutive 8kb region with different permissions. 16kb
           | pages can't do that without segfaulting every time memory is
           | used "wrong", and trying to fix that up transparently would
           | be a nightmare.
        
             | yjftsjthsd-h wrote:
             | > 16kb pages can't do that without segfaulting every time
             | memory is used "wrong", and trying to fix that up
             | transparently would be a nightmare.
             | 
             | I would natively imagine the kernel could trap that and
             | remap on the fly, at the tiny cost of murdering
             | performance. Is that untrue, or is the perf so bad that
             | it's not worth it?
        
               | plorkyeran wrote:
               | Anything which involves the kernel tracking permissions
               | at 4k granularity despite using larger pages is just
               | going to be worse in every way than using 4k pages.
        
               | dwattttt wrote:
               | It depends on how much of a program actually triggers the
               | failure case, so you can't answer in the abstract.
               | 
               | In the worst case, ~every memory access causes the kernel
               | to need to fix it, causing every memory access to be
               | several orders of magnitude worse (e.g. a hot cache hit
               | vs trapping into kernel, wiping caches, at the very least
               | hundreds more accesses).
               | 
               | EDIT: I see you suggested remapping the page permissions.
               | Maybe that helps! But maybe it adds the cost of the
               | remapping onto the worst case, e.g. the first 4kb are
               | instructions that write into the second 4kb.
        
             | bjourne wrote:
             | That's a valid point, but isn't memory protection the only
             | common user-visible effect of changed page sizes? It would
             | seem most apps which do not use write-protected memory
             | would be unaffected.
        
           | mapt wrote:
           | As a user not involved in android or linux development: I
           | don't care. Fix it. You just don't break the entire ecosystem
           | of unmaintained apps for a 3% performance improvement.
           | 
           | We maintained win32-x86 executable compatibility for decades.
           | Keeping things working might require some sort of emulation
           | layer, and it might impact performance substantially, and
           | that's fine. I can accept that.
           | 
           | "Everything just stops working" is not an option for a real
           | operating system. I don't expect to put my workshop tools
           | away and wake up in the morning to find the toolchest
           | manufacturer sent them to the landfill because they didn't
           | efficiently fit their new drawers.
           | 
           | One of the areas that Android is common in that I couldn't
           | possibly recommend is home automation. Your light switches
           | are 50-year purchases. Odds that the app based light switches
           | are working in five years are 50/50... Compound odds of
           | longer are miniscule.
        
             | Grazester wrote:
             | Is anything industrial is going to be built on Android.
             | There are no ATM's, no manufacturing CNC machines etc. One
             | my say everything that runs on Android is throw away. It is
             | only recently Samsung and Google started to aim at 7 year
             | life spans. At 7 years for an industrial piece of
             | equipment, I may not have even paid it off as yet, then
             | again is the software on these things even updated?
        
               | cbarrick wrote:
               | Point of sale systems, like Toast. Media systems on
               | airplanes. Infotainment systems in cars.
               | 
               | In fact, NCR does sell an Android-based ATM solution. [1]
               | 
               | Android is actually used somewhat widely in embedded
               | systems that need to provide a nice GUI to the user.
               | 
               | [1]: https://www.zdnet.com/article/ncr-launches-kalpana-
               | an-androi...
        
             | ars wrote:
             | I think most apps are written in Java, and according to the
             | blog post will not be affected.
             | 
             | It's only the apps written in c++ that need to be compiled,
             | and those are probably large games and heavily performance
             | critical apps.
        
         | saagarjha wrote:
         | Apps that expect 4K pages will try to enforce memory
         | protections at that granularity.
        
         | tonyhart7 wrote:
         | "but I don't see the need to dump old apps from the app store"
         | 
         | They literally remove almost 50% total android app earlier this
         | year, they clearly devoted to quality and security
        
         | altfredd wrote:
         | Google already dumps old apps from store for no reason
         | whatsoever:
         | 
         | https://android-developers.googleblog.com/2022/04/expanding-...
         | 
         | You have to update an application every year, even if it is
         | just meaningless version bump. Otherwise it will be removed
         | after 2 years. Despite saying that this policy is required to
         | ensure user security, several recent Android releases didn't
         | have any corresponding major security changes.
        
         | vineyardmike wrote:
         | > I can understand the desire for google to want devs to
         | recompile their apps, but I don't see the need to dump old apps
         | from the app store
         | 
         | It could be that Google explicitly wants to dump un(der)
         | maintained apps. Sure some might be clean and basic utilities
         | that will work till the end of time, but many are probably
         | abandonware or crummy demos and hello-world apps that look old
         | and dated. They went on a whole purge recently already.
         | 
         | The App Store market is changing as Google/Apple grapple with
         | efforts to end their monopolies. Maybe they're seeing that
         | change and trying to use their dying advantage to frame
         | themselves as the curated and reputable stores with high-
         | quality maintained and up to date apps. When distribution is
         | available from other places, they can chose their customers.
        
         | pjmlp wrote:
         | They already force apps to update to new APIs every couple of
         | years, it was the only way to stop developers to keep using
         | deprecated stuff.
        
         | jandrese wrote:
         | What if you have a data structure that straddles the 4k
         | boundary?
        
       | mkw5053 wrote:
       | I used to work closely with the Android team at Unity, and in my
       | experience, shifting large native codebases to a new page size
       | often uncovers subtle runtime assumptions beyond just replacing
       | hardcoded constants like PAGE_SIZE. I'm optimistic Google's
       | tooling will help a lot, but interested about how effectively it
       | catches these more nuanced compatibility issues like custom
       | allocators or memory pooling tuned for 4K boundaries.
        
         | HPsquared wrote:
         | Could they find those by setting page size to some absurdly
         | large value like 1MB?
        
           | majke wrote:
           | A lot of software wont work if you do that. Many jits and
           | memory allocators have opinions on page size. Also tagged
           | pointers are very common.
        
             | rwmj wrote:
             | Also quite a lot of kernel drivers allocate whole pages
             | (sometimes the device being driven requires it).
        
             | bigstrat2003 wrote:
             | This just provides yet another example of why tagged
             | pointers are a terrible idea and shouldn't be used.
             | Someday, more of the address space will get used and your
             | software will break.
        
             | vient wrote:
             | Memory page size should be transparent for tagged pointers
             | (any pointers, really), I don't see how they can be
             | affected. You have an object at address 0xAB0BA, does the
             | size of underlying page matter?
        
           | alexey-salmin wrote:
           | Tangent, but 1Mb pages aren't that absurd really. The x86-64
           | has hardware support for 4k, 2MB, and 1GB page sizes (because
           | each level of the pagemap cuts 9 bits from the virtual
           | address). Luckily it supports all 3 mixed together so
           | normally you just keep most of your data in 4kb pages and use
           | 2Mb/1Gb occasionally. But from my understanding nothings
           | prevents you from forcing 2Mb on all userspace code even
           | though Linux kernel doesn't support it.
        
         | Twirrim wrote:
         | Someone I collaborate with has been having all sorts of fun
         | with a 4k->64k page transition for stuff running on Arm. Among
         | some of the fun has been discovering memory leaks that really
         | weren't noticeable or a big deal at 4k, but now that the page
         | is 16x larger, suddenly becomes noticeable and can even cause
         | problems.
        
       | AnonC wrote:
       | > Starting _November 1st, 2025,_ all new apps and app updates
       | that use native C /C++ code targeting Android 15+ devices
       | submitted to Google Play must support 16 KB page sizes.
       | 
       | I realize that most apps wouldn't need to make changes and that a
       | recompilation would suffice, but is this time frame enough for
       | the apps that do need code changes?
        
         | extraduder_ire wrote:
         | They've mentioned this requirement before, last hn post I see
         | is from early may.
         | 
         | They only added support in android 15, in august 2024.
         | https://android-developers.googleblog.com/2024/08/adding-16-...
         | 
         | I don't know what "targetting Android 15+" means specifically.
         | Does that include anything with a lower API level?
        
           | jlokier wrote:
           | _> I don 't know what "targetting Android 15+" means
           | specifically. Does that include anything with a lower API
           | level?_
           | 
           | - On Android, apps are built with _targetSdkVersion_ set to
           | the API version you 're app is compiled for and tested
           | against, but you cam set a lower _minSdkVersion_ to the
           | lowest device API version your app will run on.
           | 
           | - On devices with API level newer than _targetSdkVersion_ ,
           | the OS looks at your app's _targetSdkVersion_ and disables
           | newer behaviours than your app is targetting. So the app
           | should run well on newer devices.
           | 
           | - On devices with API level older than _targetSdkVersion_ ,
           | but newer than (or same as) _minSdkVersion_ , your own app is
           | responsible for detecting missing APIs before trying to use
           | them, and adapting itself to the older environment.
           | 
           | - On devices with API level older than _minSdkVersion_ , your
           | app will not be run. This ensures the user gets a clear
           | failure, rather than unpredictable crashes or unexpected
           | behaviour due to missing APIs the app tries to call.
           | 
           | So, in principle, it's possible to build an app which targets
           | the most recent Android 15, while being capable of running on
           | all versions of Android back to version 1. Apps linked for 16
           | kiB page-alignment should run on older devices that use 4 kiB
           | pages too.
           | 
           | The Google Play Store enforces that _targetSdkVersion_ is
           | fairly close to the latest Android version. But it doesn 't
           | place requirements on _minSdkVersion_.
        
           | izacus wrote:
           | Android apps have a flag in their manifest which tells the OS
           | "this app was built with Android X (API level X) in mind".
           | 
           | This allows the OS to selectively enable backwards
           | compatibility and change certain behaviors (e.g. selectively
           | enforce new permissions so old apps aren't broken).
           | 
           | Play Store requires apps to target new OSes and port APIs
           | within certain time of an OS launching (usually ~2 years).
           | 
           | This avoids apps targeting older OSes to avoid new security
           | and privacy enhancements (e.g. asking for permisisons to show
           | notifications, asking for permisisons to access microphone,
           | being allowed to show a fullscreen popup ad, etc. Those
           | restrictions were all gated behind the target check.)
        
         | ohdeargodno wrote:
         | If you, yourself have native code you're trying to build, it
         | only required bumping the NDK (which is automatically bumped
         | when you upgrade the android gradle plugin), so that's mostly
         | an automatic step (provided you're not stuck on old, AGP7 build
         | scripts).
         | 
         | If you depend on a package that uses a native library, you wait
         | for them to update. Or you fork, bump AGP and rebuild.
         | 
         | It's a very minor change, unless you depend on unmaintained
         | code.
        
       | nephanth wrote:
       | From my noobish standpoint, it feels like most code shounldn't
       | care what the page size is? Why does it need te be recompiled?
       | 
       | What typically tends to break when changing it?
        
         | kevingadd wrote:
         | Off the top of my head:
         | 
         | If you rely on being able to do things like mark a range of
         | memory as read-only or executable, you now have to care about
         | page sizes. If your code is still assuming 4KB pages you may
         | try to change the protection of a subset of a page and it will
         | either fail to do what you want _or_ change way too much. In
         | both cases weird failures will result.
         | 
         | It also can have performance consequences. For example, if
         | before you were making a lot of 3.5KB allocations using mmap,
         | the wastage involved in allocating a 4KB page for each one
         | might not have been too bad. But now those 3.5KB allocations
         | will eat a whole 16KB page, making your app waste a lot of
         | memory. Ideally most applications aren't using mmap directly
         | for this sort of thing though. I could imagine it making life
         | harder for the authors of JIT compilers.
         | 
         | Some algorithms also take advantage of the page size to do
         | addressing tricks. For example, if you know your page size is
         | 4KB, the addresses '3' and '4091' both can be known to have the
         | same protection flags applied (R/W/X) and be the same kind of
         | memory (mmap'd file on disk, shared memory segment, mapped
         | memory from a GPU, etc.) This would allow any tables tracking
         | information like that to only have 4KB granularity and make the
         | tables much smaller. So that sort of trick needs to know the
         | page size too.
        
         | leidenfrost wrote:
         | Typically low level code and some manual fiddling with memory
         | by asuming page size.
         | 
         | Everything's ok until some obscure library suddenly segfaults
         | without any error
        
         | okanat wrote:
         | Because the final ELF binary is linked to contain page aligned
         | segments. Segments define how should the binary be loaded into
         | memory and what permissions they require.
         | 
         | If you have a 4KB segment that is marked Read-Write followed
         | immediately by a Read-Execute, naively loading it will open a
         | can of security issues.
         | 
         | Moreover many platform data structures like Global Object Table
         | of the dynamic executable uses addresses. You cannot simply
         | bump things around.
         | 
         | On top of that libraries like C++ standard library (or abseil
         | from Google) rely on the page size to optimize data structures
         | like hash maps (i.e. unordered_map).
        
         | magnat wrote:
         | Mostly for I/O, e.g. mmap requires file offset to be multiple
         | of the page size.
        
         | junon wrote:
         | Performance, safety and IO critical code must care, because the
         | page size affects TLB caching and is the finest granularity for
         | security flags such as read-only, no execute, etc. which are
         | critical for e.g. guard pages.
         | 
         | If your code that created two guard pages sandwiching a
         | security critical page to make sure that under/overruns caused
         | a page fault and crashed that assumed the boundary was at 4KiB,
         | but is really now at 16KiB, that means that buffer overruns now
         | will not get caught.
         | 
         | Further, code that assumed it was on a page boundary for some
         | reason, for performance reasons, will now have only a 25%
         | chance of being so.
         | 
         | It also means that MMIO physical pages that were expected to be
         | contained within a 4KiB page such that when mapped into a
         | sensitive user space driver context, neighboring MMIO control
         | blocks wouldn't be touched, might be affected too since you'll
         | get up to 3 neighboring blocks in either direction. This
         | probably doesn't happen so often, I don't know Android
         | internals much, but still something to consider.
         | 
         | This is in large part because PAGE_SIZE in a lot of C code is a
         | macro or constant, rather than something populated at runtime
         | depending on the system the code is running - something I've
         | always felt is a bit problematic.
         | 
         | That being said, code that's hard coding PAGE_SIZE won't run
         | anyway if using e.g. mmap() because it validates the page size
         | and will error on mismatch.
         | 
         | This is going to wreak general havoc for a while no matter how
         | you spin it.
        
         | notepad0x90 wrote:
         | most code shouldn't but you don't know what the library you're
         | using is doing behind the scenes. the few code that do care, if
         | a lot of people use them as a dependency, that could get real
         | messy real fast.
        
       | londons_explore wrote:
       | If you're making the migration at all, you really ought to be
       | going for fully variable page sizes, otherwise 5 years from now
       | there'll be a 64K page size CPU and suddenly everyone has to
       | recompile everything again and there is another compatibility
       | wall...
        
         | rwmj wrote:
         | Is there a such a thing? Page size gets baked into things like
         | executable layouts, plus any place that uses the PAGE_SIZE
         | constant (instead of sysconf(_SC_PAGESIZE)).
        
           | londons_explore wrote:
           | Indeed it would take redesigning a bunch of things to make
           | runtime variable page size an option.
        
         | bjourne wrote:
         | 4 KiB page sizes have been used since the 1960's. More memory
         | doesn't necessarily mean that larger pages are beneficial.
         | Maybe 16 KiB is better for Android? Maybe. There really is no
         | clear consensus on what the optimal page size for modern
         | architectures should be.
        
       | rwmj wrote:
       | From the experience implementing 64K page sizes on aarch64 in
       | Fedora & RHEL, this is not going to be a simple transition. All
       | sorts of things will break in subtle, strange and interesting
       | ways. Good luck to the Android team :-)
        
         | croemer wrote:
         | I think you meant "Android developers" that are forced to
         | switch their apps.
        
       | londons_explore wrote:
       | This is dumb. The abstraction is at the wrong level.
       | 
       | Applications should assume the page size is 1 byte. One should be
       | able to map, protect, etc memory ranges down to byte granularity
       | - which is the granularity of everything else in computers. One
       | fewer thing for programmers to worry about. History has shown
       | that performance hacks with ongoing complexity tend not to
       | survive (eg. interlaced video).
       | 
       | At the hardware level, rather than picking a certain number of
       | bits of the address as the page size, you have multiple page
       | tables, and multiple TLB caches - eg. one for 1 megabyte pages,
       | one for 4 kilobyte pages, and one for individual byte pages. The
       | hardware will simultaneously check all the tables (parallelism is
       | cheap in hardware!).
       | 
       | The benefit of this is that, assuming the vast majority of bytes
       | in a process address space are made of large mappings, you can
       | fit far more mappings in the (divided up) TLB - which results in
       | better performance too, whilst still being able to do precise
       | byte-level protections.
       | 
       | The OS is the only place there is complexity - which has to find
       | a way to fit the mappings the application wants into what the
       | hardware can do (ie. 123456 bytes might become 30 4-kilobyte
       | pages and 576 byte pages.).
        
         | growse wrote:
         | > One should be able to map, protect, etc memory ranges down to
         | byte granularity - which is the granularity of everything else
         | in computers.
         | 
         | But you can do this, you simply have to pay the cost of using
         | PAGE_SIZE of memory per byte you want to protect?
        
         | ohdeargodno wrote:
         | Dozens of years of kernel building, dozens of OSes, dozens of
         | physical architectures, all having settled on minimum 4KB pages
         | being a right balance between performance and memory usage,
         | wiped away by a single offhand comment with no knowledge about
         | the situation. Now that's HN.
         | 
         | Just the sheer TLB memory usage and performance implication of
         | doing single byte pages would send CPU performance back to the
         | stone age.
        
           | FullyFunctional wrote:
           | Completely false. The 4 KiB page size came from a machine
           | with a total of 512 KiB (1962 Atlas, 3072B pages, 96k 48b
           | words). It hasn't scaled at all for inertia reasons and it
           | has real and measurable costs. 64 KiB would have been the
           | better choice IMO, but 16 is better than 4.
        
             | ohdeargodno wrote:
             | Hence the "minimum" part. The thread is literally about
             | Android being compiled for 16KB pages, CPU support for
             | larger pages has grown, easily up to 4MB for most consumer
             | CPUs.
             | 
             | Going down _lower_ than 4KB is purely a waste of memory and
             | performance.
        
           | londons_explore wrote:
           | My proposed design has _many_ page sizes - nothing stops a
           | software developer making all mappings multiples of 4kb and
           | not using the byte sized pages.
           | 
           | My example was 1mb, 4kb and 1 byte pages - but a real design
           | would probably use every power of two, or every even power of
           | two to get best use of the TLB space.
           | 
           | It hasn't been done before because of a chicken and egg
           | problem. CPU designers don't build it because no OS has the
           | ability to use it, and no OS uses it because no CPU supports
           | it. It would be a substantial amount of work for both
           | parties.
        
         | murderfs wrote:
         | Your response to a change that's motivated by performance
         | improvements is to suggest switching to a scheme that'll have
         | catastrophically worse performance?
        
           | londons_explore wrote:
           | It would likely have better performance for similar power and
           | silicon area, because a hierarchical TLB will have a higher
           | hit rate for the same number of transistors.
        
         | pjc50 wrote:
         | If you're going to go that far, you might as well move malloc()
         | into hardware and start using ARM-style secure tagged pointers.
         | Then finally C users can be free of memory allocation bugs.
        
       | croemer wrote:
       | "offering improved performance gains" is a pleonasm. "offering
       | performance gains" works just fine.
        
       | Eric_WVGG wrote:
       | > This table describes who needs to transition and recompile
       | their apps
       | 
       | information design is my passion
        
         | butz wrote:
         | Table added as image, alt text vaguely explains table contents
         | and has a spelling error. Great.
        
       | gok wrote:
       | It's kind of too bad Linux to doesn't just support multiple base
       | page sizes.
        
       ___________________________________________________________________
       (page generated 2025-07-15 23:02 UTC)