AutoJs6 icon indicating copy to clipboard operation
AutoJs6 copied to clipboard

怎么获得AutoJS剩余内存(运存)?

Open wengzhenquan opened this issue 2 months ago • 4 comments

我下载文件的时候会报oom(内存不足)异常, 但我发现设备本身内存还是很充足的。

使用device.getAvailMem()获取的内存也还有2G,而我只是下载几十M的文件(下载多个文件,每个几十M)。 所以我怀疑是jvm启动内存配置,或其它方面的设置,所以不知道能否修改启动内存配置。

自带的http请求res.body.byte(),只能一次性获取所有byte,也不能按照流,分段下载。如果实在不行,也许只能使用okhttp,分段下载也许能够解决问题。

或者有没有办法在每个文件下载完后,能释放内存?(下载多个文件,前面一部分不会报oom,随着数量增多,才会报oom。)

我使用 runtime.gc; java.lang.System.gc(); 貌似不能有效的gc来释放内存。

遇到oom后,即便停止下载,再次重新下载依旧oom。只能关闭AutoJS6应用,重新启动才能解决

wengzhenquan avatar Sep 30 '25 02:09 wengzhenquan

Thread[ScriptThread-90[/data/user/0/org.autojs.autojs6/cache/tmp-scripts/tmp-1759226147692.js] (Spawn-4),5]: Failed to allocate a 55224272 byte allocation with 13044634 free bytes and 12MB until OOM, target footprint 536870912, growth limit 536870912 (WrappedRuntimeException.kt#19)

wengzhenquan avatar Sep 30 '25 10:09 wengzhenquan

Image

oom异常不好捕获,不好处理,怎么办?

wengzhenquan avatar Nov 03 '25 11:11 wengzhenquan

OOM 异常难以捕获, 更难以定位处理, AutoJs6 目前也难以针对每一个 OOM 异常给出明确的解决方案. 你可以尝试将代码最小化, 用来做极限测试 (while + 固定方法 + 简单参数变化), 判断是否某个方法会确定性导致 OOM, 然后我可以根据上述确定的范围排查可能造成 OOM 的代码.

另外你提到:

自带的 http 请求 res.body.byte(), 只能一次性获取所有 byte, 也不能按照流, 分段下载. 如果实在不行, 也许只能使用 okhttp, 分段下载也许能够解决问题. 这是一个很好的思路. 目前 AutoJs6 很难在 JavaScript 脚本层面实现, 但未来 AutoJs6 会在 http 模块 body 对象增加 stream/saveToFile/close 方法, 专门用来处理流数据以及文件下载需求.

功能实现后的调用示例代码:

const URL = 'https://github.com/SuperMonster002/Hello-Sockpuppet/raw/refs/heads/master/%5Bauto.js%5D%5B4.1.1_alpha2%5D%5Barm-v7a%5D(b69a4e23).apk';

const result = http.get(URL).body.saveToFile('./[auto.js][4.1.1_alpha2][arm-v7a](b69a4e23).apk');

// HttpSaveResult {
//   code: 0,
//   bytesCopied: 15743263(15.74 MiB),
//   path: '/storage/emulated/0/Scripts/[auto.js][4.1.1_alpha2][arm-v7a](b69a4e23).apk',
//   error: null,
// }
console.log(result); 

console.log(result.code); // 0
console.log(result.path); // /storage/emulated/0/Scripts/[auto.js][4.1.1_alpha2][arm-v7a](b69a4e23).apk
console.log(result.success); // true
console.log(result.error); // null
console.log(fmt.bytes(result.bytesCopied, { strict: true })); // 15.74 MiB

SuperMonster003 avatar Nov 10 '25 06:11 SuperMonster003

System.gc() 只是一个信号, 并非立即执行. 它相当于告诉 JVM, "建议尽快进行垃圾回收". 垃圾回收本身是一个消耗资源的过程, 若可立即执行, 频繁 gc 会导致应用性能受到严重影响. 不能依赖 System.gc() 做内存释放.

另外当前 issue 的标题是关于如何获取 AutoJs6 剩余运存的, 我还没有提供这方面的帮助. 鉴于 issue 的内容与之不具备足够的关联性, 如果你确实需要, 我再另外提供上述内容的示例代码.

如有其他需求或见解, 欢迎继续讨论.

SuperMonster003 avatar Nov 10 '25 06:11 SuperMonster003