[Sony Xperia E3] UCyborg:
Why does the OS regenerate files in /data/dalvik-cache folder even for apps that already have .odex file in /system/app/<app name>/oat/arm?

This is dumb and just wastes space. I installed several apps on /system and generated .odex file for them with dex2oat utility.

I invoked it using the following terminal commands (need to type su to get root rights first):

cd /system/app/app-name

mkdir oat

mkdir oat/arm

dex2oat --dex-file=app-name.apk --oat-file=oat/arm/app-name.odex --compiler-filter=interpret-only

I realize this is not the most optimal performance-wise (compiler filter), but should be the default setting when installing new apps. First boot with cleared /data partition resulted in dalvik-cache folder that wasn't too big.

The OS apparently runs dex2oat by itself when idle and plugged in with the full battery. So today, I suddenly got from internal storage that previously had little below 900 MB of free space to just little over 200 MB.

I think the result now is that apps for which I generated .odex file by myself are better optimized, judging by reference to filter-speed if you look at the generated .dex file with hex editor. Though I noticed Settings app also opens faster.

But I'm back to the old problem I already had with stock OS - very little space to play with, the issue I'd like to solve without buying a new phone. Obviously, I've got a crapload of redundant .dex files since apps that come with the system are already optimized. So what now? I have a lot of questions, but can't find answers. In the end, I'd like to have all optimized files for updated system apps on /system, not wasting space on /data.

Is the data that dex2oat ran in the background once written somewhere? Where?

Is it written somewhere which apps were optimized?

What's the logic for determining that the app has to be optimized? The source file BackgroundDexOptService.java mentions: Schedule a one-off job which scans installed packages and updates out-of-date oat files. If there's a logic, it's pretty bad if it can't figure out that system apps are pre-optimized.

If there's no way to make this background optimization behave like it's supposed to, what then? Just turn it off by adding pm.dexopt.disable_bg_dexopt=true to /system/build.prop and hope it works? The property is referenced in the mentioned source file, though I didn't find the one from this build specifically, just the newer one from AOSP, so not sure if this build of LineageOS even supports it.

When I first installed the OS and placed my favorite apps' APKs in /system/app/app-name and booted for the first time, I moved individual .dex files from /data/dalvik-cache/arm to /system/app-name/oat/arm and named them app-name.odex. After wiping /data, .dex files for affected apps were generated in /data/dalvik-cache.

But if I generated .odex files with dex2oat and wiped /data, then those files were not generated at first boot, only when that background optimization service ran.

Does that mean those files the system generates can't be simply moved under /system? Is there an explanation for this behavior? Is the file the system generates and place under /data/dalvik-cache effectively different from the one I generated by invoking dex2oat manually?

As said earlier, I'm unable to find any useful information. There doesn't seem to be anything for odexing ROMs for newer Android versions neither. It used to be simple back in the Gingerbread days.

Rooting also wasn't the most straightforward. You have to flash boot_TWRP-v3.2.1_Magisk-v15.2.img and install an older Magisk Manager app as the latest one just crashes, I used version 5.8.2. I didn't test which version exactly is the latest that works, but this one does.

Also, the boot image has to be patched since it doesn't allow ADB in recovery mode, only ADB sideload mode works by default.

I used that Android Image Kitchen package for Windows to unpack the image. Now, you normally also have to get to content of ramdisk/sbin/ramdisk-recovery.cpio, which requires proficiency with certain tools you get on Linux. Fortunately, in this case, you can just open ramdisk-recovery.cpio in hex editor and replace the first occurrence of ro.adb.secure=1 with ro.adb.secure=0, save then repack the image.