Android 12 introduced a lot of changes, although not all of them are really user-oriented. Features like the massive Material You overhaul are obviously pushed in your face and hard to miss, but something like Digital Car Key support could be easier to miss. However, one change that might even be entirely undocumented will wreak havoc on apps like Termux, and it’s the introduction of a pretty aggressive background process killer.
For context, Termux is a Linux terminal emulator that you can get on Android, and Termux’s package management system looks a lot like Debian’s Advanced Package Tool (APT) in that you can search, install and uninstall with the command apt. Termux only installs a few basic packages out of the box, to reduce the size of the APK on the Play Store, but allows you to install any additional packages you desire. People will often use Termux to turn older smartphones into mini-servers, or use it to run other programs that aren’t typically for smartphones. One common use is even to natively configure youtube-dl, as you can run Python scripts using Termux on your smartphone.
In Android 12, however, it was discovered that a mechanism to monitor fork child processes started by apps and kill them if they consume too much CPU if the app is in the background (via Mishaal rahman) has been presented. It also limits the number of child processes that parent processes can generate to 32, which significantly limits the number of operations an application can perform in the background. This limit of 32 child processes actually applies to the entire system, not just per application, which means that other applications with child processes will also contribute to this limit. I have tested on the Google Pixel 6 Pro, and I can confirm that the PhantomProcessKiller exists and can potentially wreak havoc on Termux.
Android 12’s ghost process killer kills background processes
Android 12 introduced some restrictions on background processes; the first is that child processes of applications consuming too much CPU in the background will be killed if the parent process is also in the background. The second restriction introduced is a limit on the number of child processes that can be active at any given time. From the commit history, it looks like Google was trying to crack down on malicious background processes.
“Applications could use Runtime.exec () to spawn a child process and the framework will have no idea what its lifecycle is. Now follow these processes whenever we find them – currently, when sampling CPU stats, they might be spotted. If it consumes too much CPU while its parent application process is also in the background, kill it. By default, we allow up to 32 such processes; the process with their parents’ worst adj oom score will be killed if there are too many.
Of course, Android smartphones are already known to kill background apps. Almost all of the major OEMs are committing to it in one way or another, and companies like OnePlus, Samsung, and Xiaomi are considered some of the worst. Although the AOSP has background application restrictions, it is common for manufacturers to create their own restrictions on top of the AOSP. However, these are fairly strict limitations for power users and encourage behaviors that power users have vocally objected to for a long time. Maybe this will increase battery life in the long run, but there’s apparently no way to turn it off either.
Android 12 Ghost Process Killer Trigger
As the commit says, 32 of these processes are allowed, and I checked this on my Google Pixel 6 Pro with the following command.
adb shell "/system/bin/dumpsys activity settings"
In the output of this command, there is a constant called “max_phantom_processes” with a value of 32. In this context, a “ghost process” is considered by the Android system to be a child process running in the background. If you have an Android 12 device, you can use Termux to spawn over 32 child processes by creating a bash script somewhere on your storage containing the following code and running it (credits to agnostic-apollo on GitHub, a developer involved with Termux):
for i in $(seq 40); do
sha256sum /dev/zero &
done
To run it, in Termux, navigate to the folder where you saved the script and type the following:
sh filename.sh
If your phone starts to be slow, it means it’s working. The above code generates 40 sha256sum operations in the background (indicated by the ampersand) taking the / dev / zero input file. sha256sum will give the SHA-256 hash of any file given as input. The reason / dev / zero is used is that it is an infinitely long file that contains zero values as long as it is read, which means that the sha256sum operation will never reach the end of the file, serving as a good test of resistance to ensure continuous background operations.
After a few seconds to a minute, the following may appear:
“Signal 9” is a signal sent to the process forcing it to stop, and this signal is sent by the Linux scheduler. The reason the message appears is that the bash terminal is also technically a child process of Termux, and Android 12 ends up killing the bash terminal in the demo above. In the logcat output, you can see the following:
11-02 13:01:52.507 1444 1762 I ActivityManager: Killing PhantomProcessRecord {623260a 7362:7284:nightwatch.txt/u0a227}: Trimming phantom processes
11-02 13:01:52.507 1444 1762 I ActivityManager: Killing PhantomProcessRecord {bf3d88c 24220:24040:nightwatch.txt/u0a237}: Trimming phantom processes
11-02 13:01:52.507 1444 1762 I ActivityManager: Killing PhantomProcessRecord {b160bd5 27316:27269:bash/u0a340}: Trimming phantom processes
11-02 13:01:52.507 1444 1762 I ActivityManager: Killing PhantomProcessRecord {bbc1fea 27371:27269:sha256sum/u0a340}: Trimming phantom processes
11-02 13:01:52.507 1444 1762 I ActivityManager: Killing PhantomProcessRecord {9cf12db 27372:27269:sha256sum/u0a340}: Trimming phantom processes
11-02 13:01:52.507 1444 1762 I ActivityManager: Killing PhantomProcessRecord {54bf178 27373:27269:sha256sum/u0a340}: Trimming phantom processes
11-02 13:01:52.507 1444 1762 I ActivityManager: Killing PhantomProcessRecord {fb89051 27374:27269:sha256sum/u0a340}: Trimming phantom processes
11-02 13:01:52.507 1444 1762 I ActivityManager: Killing PhantomProcessRecord {d3450b6 27375:27269:sha256sum/u0a340}: Trimming phantom processes
11-02 13:01:52.507 1444 1762 I ActivityManager: Killing PhantomProcessRecord {2a201b7 27376:27269:sha256sum/u0a340}: Trimming phantom processes
11-02 13:01:52.507 1444 1762 I ActivityManager: Killing PhantomProcessRecord {60aad24 27377:27269:sha256sum/u0a340}: Trimming phantom processes
11-02 13:01:52.507 1444 1762 I ActivityManager: Killing PhantomProcessRecord {124e08d 27378:27269:sha256sum/u0a340}: Trimming phantom processes
11-02 13:01:52.507 1444 1762 I ActivityManager: Killing PhantomProcessRecord {32cc242 27379:27269:sha256sum/u0a340}: Trimming phantom processes
11-02 13:01:52.511 1444 1764 I ActivityManager: Process PhantomProcessRecord {b160bd5 27316:27269:bash/u0a340} died
11-02 13:01:52.511 1444 1764 I ActivityManager: Process PhantomProcessRecord {9cf12db 27372:27269:sha256sum/u0a340} died
11-02 13:01:52.511 1444 1764 I ActivityManager: Process PhantomProcessRecord {414579a 27434:27269:top/u0a340} died
11-02 13:01:52.511 1444 1764 I ActivityManager: Process PhantomProcessRecord {32cc242 27379:27269:sha256sum/u0a340} died
11-02 13:01:52.511 1444 1764 I ActivityManager: Process PhantomProcessRecord {bbc1fea 27371:27269:sha256sum/u0a340} died
11-02 13:01:52.511 1444 1764 I ActivityManager: Process PhantomProcessRecord {bf3d88c 24220:24040:nightwatch.txt/u0a237} died
11-02 13:01:52.512 1444 1764 I ActivityManager: Process PhantomProcessRecord {60aad24 27377:27269:sha256sum/u0a340} died
11-02 13:01:52.516 1444 1764 I ActivityManager: Process PhantomProcessRecord {623260a 7362:7284:nightwatch.txt/u0a227} died
11-02 13:01:52.516 1444 1764 I ActivityManager: Process PhantomProcessRecord {124e08d 27378:27269:sha256sum/u0a340} died
11-02 13:01:52.517 1444 1764 I ActivityManager: Process PhantomProcessRecord {fb89051 27374:27269:sha256sum/u0a340} died
11-02 13:01:52.519 1444 1764 I ActivityManager: Process PhantomProcessRecord {54bf178 27373:27269:sha256sum/u0a340} died
11-02 13:01:52.532 1444 1764 I ActivityManager: Process PhantomProcessRecord {2a201b7 27376:27269:sha256sum/u0a340} died
11-02 13:01:52.545 1444 1764 I ActivityManager: Process PhantomProcessRecord {d3450b6 27375:27269:sha256sum/u0a340} died
The important line is the one that mentions that the “bash” process was cut and then died, which is why Termux stops working. While I’m not sure what “nightwatch.txt” is, a quick Google search seems to suggest that it’s related to Facebook and Facebook Messenger, two apps that I installed. I tested this with the adaptive battery turned off and made sure no battery optimization was applied to Termux either.
After testing is complete, it is likely that some of the sha256sum operations will continue in the background (and pressing Enter will force Termux to close), so reopen Termux and type the following:
killall sha256sum
While such a limitation makes sense for some apps, apps that power users might be more inclined to use (like Termux) will suffer. It can also have an effect on other apps that power users also use, such as Tasker. This is a limitation that does not seem possible to overcome yet and which introduces even more limitations on background applications on top of all the other proprietary restrictions imposed by manufacturers. In the current GitHub thread, agnostic-apollo mentions the following regarding a logcat that was emailed to them:
“All 32 Logcat PhantomProcessRecord tracked belong to com.wsandroid.suite and the termux bash was one of the processes that were killed. So, as mentioned above, the limit of 32 processes is for all applications combined “
In a fun way, I performed the same tests on a Xiaomi 11T Pro running Android 11 and confirmed that the behavior does not exist on this particular device in this configuration, even though Xiaomi devices are known for the limitations of background applications. It is, oddly enough, one of the most stringent background app management policies introduced on any Android smartphone, as there is no way around it. Even on Xiaomi devices and OnePlus devices, it is possible to deactivate more of it, and for some people, just turning off all battery optimizations on those devices for them to be happy. The phantom process killer, on the other hand, can’t even be disabled.
If you are relying on Termux for a lot of device operations that are intensive with lots of background processes, it may be useful to pause the upgrade for now until there is more. information. If you are not a power user, this is probably not something you really need to worry about.