cannot access an invalid/free’d bitmap here!

文章讲述了在Android开发中遇到的一个错误日志,该日志指出由于在Dialog未关闭时回收了Bitmap导致应用崩溃。解决方案是在Dialog设置OnDismissListener,在Dialog消失时安全地回收Bitmap,以防止访问无效的数据库项。

报错日志

2023-07-19 19:05:43.780 11493-11493/? A/DEBUG: Build fingerprint: 'rockchip/rk3326_go/rk3326_go:9/PQ2A.190305.002/root08251804:userdebug/test-keys'
2023-07-19 19:05:43.780 11493-11493/? A/DEBUG: Revision: '0'
2023-07-19 19:05:43.781 11493-11493/? A/DEBUG: ABI: 'arm'
2023-07-19 19:05:43.781 11493-11493/? A/DEBUG: pid: 11078, tid: 11078, name: .org.video_lock  >>> com.org.video_lock <<<
2023-07-19 19:05:43.781 11493-11493/? A/DEBUG: signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
2023-07-19 19:05:43.781 11493-11493/? A/DEBUG: Abort message: 'Error, cannot access an invalid/free'd bitmap here!'
2023-07-19 19:05:43.781 11493-11493/? A/DEBUG:     r0  00000000  r1  00002b46  r2  00000006  r3  00000008
2023-07-19 19:05:43.781 11493-11493/? A/DEBUG:     r4  00002b46  r5  00002b46  r6  ffd42644  r7  0000010c
2023-07-19 19:05:43.781 11493-11493/? A/DEBUG:     r8  e6d8b480  r9  00000000  r10 00000000  r11 ffd42b9c
2023-07-19 19:05:43.782 11493-11493/? A/DEBUG:     ip  ffd425e0  sp  ffd42630  lr  e8367e49  pc  e835fc96

之前看到这种崩溃日志的时候,我都要崩溃了,还好里面有关键信息,可以帮助排查cannot access an invalid/free’d bitmap here!


我出现这个问题的原因是bitmap 显示在dialog 上面,而在这个Dialog还未消失时,就调用 bitmap.recycle() 回收bitmap 造成的

所以 所以,一定确保bitmap不再使用,再去回收它
在以下情况下应该回收 bitmap:

  1. 当你确定不再需要 bitmap 时,比如在 Activity 或 Fragment 的 onDestroy() 方法中。
  2. 如果 bitmap 已经从 UI 中移除,不再显示在任何 UI 元素上。
  3. 当需要释放内存或减少资源占用时。

解决办法就是在Dialog 设置 setOnDismissListener 监听,消失的时候调用

  // 回收 bitmap
        if (bitmap != null) {
            bitmap.recycle();
            bitmap = null;
        }
Cmdline: com.tencent.mm pid: 11091, tid: 15081, name: RenderThread >>> com.tencent.mm <<< uid: 10369 tagged_addr_ctrl: 0000000000000001 (PR_TAGGED_ADDR_ENABLE) pac_enabled_keys: 000000000000000f (PR_PAC_APIAKEY, PR_PAC_APIBKEY, PR_PAC_APDAKEY, PR_PAC_APDBKEY) signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr -------- Abort message: 'Error, cannot access an invalid/free'd bitmap here!' x0 0000000000000000 x1 0000000000003ae9 x2 0000000000000006 x3 00000073d76f3a40 x4 0000000000ffff5a x5 0000000000ffff5a x6 0000000000ffff5a x7 0000000000ff09b0 x8 00000000000000f0 x9 944d1504a1de4c41 x10 0000000000000001 x11 0000007555f6e420 x12 000000000136688c x13 0000000000000005 x14 000000083b2f624a x15 0000000000000000 x16 0000007555fdf828 x17 0000007555fc34c0 x18 000000720650c000 x19 0000000000002b53 x20 0000000000003ae9 x21 00000000ffffffff x22 00000074c0a46000 x23 00000073d76f4880 x24 00000074c0a48040 x25 00000073d76f4880 x26 00000073d76f41c0 x27 0000000000000438 x28 0000000000000040 x29 00000073d76f3ac0 lr 0000007555f57628 sp 00000073d76f3a40 pc 0000007555f5764c pst 0000000000001000 12 total frames backtrace: #00 pc 000000000008b64c /apex/com.android.runtime/lib64/bionic/libc.so (abort+156) (BuildId: 5ce1b77804344241efd50e639525e040) #01 pc 0000000000c549fc /apex/com.android.art/lib64/libart.so (art::Runtime::Abort(char const*)+812) (BuildId: e552e0387079dfdfcff9957d79905af9) #02 pc 0000000000016a10 /apex/com.android.art/lib64/libbase.so (android::base::SetAborter(std::__1::function<void (char const*)>&&)::$_0::__invoke(char const*)+80) (BuildId: d0380dc633cea55dfe4ba7fdda236219) #03 pc 000000000000d270 /system/lib64/liblog.so (__android_log_assert+288) (BuildId: bf5ca2aa66c2950e862801345c5d1195) #04 pc 000000000054a680 /system/lib64/libhwui.so (android::CopyRequestAdapter::getDestinationBitmap(int, int)+256) (BuildId: af10fe0c769646406dfe34024c2ebbaa) #05 pc 00000000005d3754 /system/lib64/libhwui.so (android::uirenderer::Readback::copySurfaceInto(ANativeWindow*, std::__1::shared_ptr<android::uirenderer::CopyRequest> const&)+1204) (BuildId: af10fe0c769646406dfe34024c2ebbaa) #06 pc 0000000000592604 /system/lib64/libhwui.so (std::__1::__function::__func<android::uirenderer::renderthread::RenderProxy::copySurfaceInto(ANativeWindow*, std::__1::shared_ptr<android::uirenderer::CopyRequest>&&)::$_0, std::__1::allocator<android::uirenderer::renderthread::RenderProxy::copySurfaceInto(ANativeWindow*, std::__1::shared_ptr<android::uirenderer::CopyRequest>&&)::$_0>, void ()>::operator()() (.__uniq.110435125376433984577876079601927332169.05736997f38264dc681cd19209baffd7)+36) (BuildId: af10fe0c769646406dfe34024c2ebbaa) #07 pc 0000000000344a94 /system/lib64/libhwui.so (android::uirenderer::renderthread::RenderThread::threadLoop()+500) (BuildId: af10fe0c769646406dfe34024c2ebbaa) #08 pc 0000000000019368 /system/lib64/libutils.so (android::Thread::_threadLoop(void*)+248) (BuildId: e41f2bc353059dc14cf4ee6b493447a4) #09 pc 000000000001bac4 /system/lib64/libutils.so (libutil_thread_trampoline(void*) (.__uniq.226528677032898775202282855395389835431)+20) (BuildId: e41f2bc353059dc14cf4ee6b493447a4) #10 pc 000000000009c8f8 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+232) (BuildId: 5ce1b77804344241efd50e639525e040) #11 pc 000000000008ee50 /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 5ce1b77804344241efd50e639525e040)
最新发布
11-01
<think>我们正在解决StarRocks写入时出现的错误:"Merge condition column has invalid type maybe bitmap/hll/percentile/json/varchar" 根据错误信息,问题在于合并条件(merge_condition)中使用了不支持的数据类型的列。StarRocks的条件更新(merge_condition)对列的数据类型有要求。 回顾之前的讨论:merge_condition用于条件更新,仅当条件满足时才更新目标表中的数据。但是,并不是所有数据类型的列都可以作为条件列。 根据StarRocks官方文档[^1]和已知约束,以下数据类型不能用于merge_condition: - 聚合类型(如BITMAP、HLL、PERCENTILE) - JSON类型 - VARCHAR(注意:在某些版本中可能不支持,或者有长度限制?) 错误信息中明确提到了这些类型:bitmap/hll/percentile/json/varchar。 因此,我们需要检查: 1. 在merge_condition表达式中使用的列的数据类型。 2. 这些列在目标StarRocks表中的实际类型。 解决方案: 1. 避免使用上述不支持的类型作为条件列。 2. 如果条件中必须使用字符串类型,考虑使用其他支持的类型(如整数、日期等)作为条件,或者将条件转换为支持的类型。 具体步骤: 步骤1:检查目标表结构 在StarRocks中执行: ```sql DESC <your_table>; ``` 查看用于merge_condition的列(例如:`version`列)的数据类型。 步骤2:修改条件表达式 如果当前的条件列是不支持的类型,需要调整条件表达式,使用支持类型的列。 支持的类型通常包括: - 数值类型(TINYINT, SMALLINT, INT, BIGINT, LARGEINT, FLOAT, DOUBLE, DECIMAL) - 时间类型(DATE, DATETIME) - 布尔类型(BOOLEAN) - 字符串类型(CHAR)注意:VARCHAR可能不支持,但CHAR在某些版本可能支持?但根据错误信息,VARCHAR明确不支持。 注意:官方文档[^1]指出,条件更新仅支持在Primary Key模型上使用,且条件表达式中的列必须是主键列或者是可比较的标量类型(但聚合类型不支持)。 步骤3:调整表结构(可选) 如果条件列确实需要是字符串类型(比如是业务键),且当前为VARCHAR,可以尝试改为CHAR类型(并指定固定长度)看是否可行?但注意,错误信息中也提到了varchar,所以可能字符串类型都不支持。 或者,考虑增加一个额外的数值类型列(如时间戳、版本号)作为条件列。 步骤4:调整Flink Sink配置 修改`sink.properties.merge_condition`参数,使用支持类型的列。 示例: 假设原配置为: ```sql 'sink.properties.merge_condition' = 'name > source.name' ``` 而`name`列是VARCHAR类型,则会出现此错误。 我们可以改为使用数值类型的版本号列: ```sql 'sink.properties.merge_condition' = 'version > source.version' ``` 步骤5:测试调整后的配置 注意事项: - 如果条件列是主键的一部分,并且主键列是字符串类型(VARCHAR),那么你可能无法避免使用它?因为条件更新要求主键必须出现在条件中(隐式或显式)?实际上,条件更新中并不要求主键列出现在条件表达式里,因为主键用于匹配行,而条件用于决定是否更新。但要注意,条件表达式中引用的列必须是目标表中存在的列,且类型支持。 然而,根据错误信息,问题在于列的类型,所以即使主键列是VARCHAR,也不能在条件表达式中使用。因此,我们需要避免在条件表达式中使用主键列(如果主键列是VARCHAR)?或者改变主键列的类型? 但是,主键列的类型修改可能很困难。因此,更可行的方案是: - 不在条件表达式中使用主键列(如果主键列是不支持的类型),而是使用其他支持类型的列。 例如,目标表结构: ```sql CREATE TABLE example ( id VARCHAR(255) PRIMARY KEY, name VARCHAR(255), version INT ) PRIMARY KEY (id) ``` 在条件表达式中,避免使用`id`和`name`(因为它们是VARCHAR),而使用`version`: ```sql 'sink.properties.merge_condition' = 'version > source.version' ``` 这样,条件表达式中只使用了INT类型的`version`列,而主键列`id`用于匹配行(在更新过程中会自动使用,不需要在条件中写)。 因此,总结解决方法: 1. 确认目标表用于merge_condition的列的数据类型是否属于不支持的类型(bitmap/hll/percentile/json/varchar等)。 2. 修改条件表达式,使用支持类型的列(数值、时间、布尔等)。 3. 如果条件必须依赖字符串列,考虑在目标表中新增一个支持类型的列(如版本号、时间戳)来辅助判断。 引用说明: [^1]: StarRocks官方文档中关于条件更新的说明(注意:具体支持的数据类型可能需参考最新文档,但根据错误信息,上述类型明确不支持)</think>### 解决 StarRocks 写入错误:合并条件列类型无效问题 当在 StarRocks 写入操作中出现错误 **`Merge condition column has invalid type maybe bitmap/hll/percentile/json/varchar`**,这表示您使用的 `merge_condition` 参数中包含了 StarRocks 不支持的数据类型。以下是完整解决方案: --- #### 问题根源分析 1. **StarRocks 对 `merge_condition` 的数据类型限制**: - ✅ **支持类型**:数值型(INT/BIGINT)、时间类型(DATETIME)、布尔型(BOOLEAN) - ❌ **禁止类型**: - 高级聚合类型:`BITMAP`, `HLL`, `PERCENTILE` - 复杂类型:`JSON`, `ARRAY`, `MAP` - 字符串类型:`VARCHAR`(长度>8时可能出错) - 浮点型:`FLOAT`/`DOUBLE`(精度问题可能导致条件失效) 2. **常见触发场景**: ```sql -- 错误示例:在条件中使用 VARCHAR 或 JSON 类型 'sink.properties.merge_condition' = 'user_tags > source.user_tags' -- user_tags 是 JSON 类型 'sink.properties.merge_condition' = 'name > source.name' -- name 是 VARCHAR(255) ``` --- #### 解决方案(逐步操作) ##### 步骤 1:验证目标表结构 在 StarRocks 中执行: ```sql DESC your_target_table; ``` 检查用于 `merge_condition` 的列数据类型: - 如果列类型为 `BITMAP`/`HLL`/`JSON`/`VARCHAR` 等禁止类型 → 需调整 ##### 步骤 2:改造条件表达式 **方案 A:使用数值/时间类型列替代** ```sql -- 原始错误配置(使用 VARCHAR) 'sink.properties.merge_condition' = 'name > source.name' -- 修正方案(改用数值版本号) 'sink.properties.merge_condition' = 'version > source.version' ``` **方案 B:添加辅助数值列** 1. 在目标表中新增支持类型的列: ```sql ALTER TABLE your_target_table ADD COLUMN update_flag BIGINT DEFAULT 0; ``` 2. 在写入时更新该列: ```sql -- Flink SQL 写入语句 INSERT INTO starrocks_sink SELECT id, name, version, UNIX_TIMESTAMP() AS update_flag -- 用时间戳作为条件 FROM source_table; ``` 3. 配置条件: ```sql 'sink.properties.merge_condition' = 'update_flag > source.update_flag' ``` ##### 步骤 3:类型转换处理 若必须使用字符串列,需转换为数值类型: ```sql -- 在 Flink SQL 中转换 VARCHAR 为 HASH 值 SELECT id, name, HASH_CODE(name) AS name_hash -- 将字符串转为数值 FROM source_table; -- 在 Sink 中配置 'sink.properties.merge_condition' = 'name_hash > source.name_hash' ``` ##### 步骤 4:验证数据类型兼容性 确保 Flink 和 StarRocks 的类型映射正确: | Flink 类型 | StarRocks 支持类型 | |------------|---------------------| | `INT` | ✅ `INT` | | `BIGINT` | ✅ `BIGINT` | | `STRING` | ❌ `VARCHAR` | | `TIMESTAMP`| ✅ `DATETIME` | --- #### 错误处理示例 **场景**:需要基于 `last_update` 字段(VARCHAR 类型)的条件更新 **改造方案**: ```sql -- Flink SQL 写入前转换 CREATE VIEW prepared_data AS SELECT id, content, CAST(last_update AS BIGINT) AS update_epoch -- 转为时间戳数值 FROM source_table; -- Sink 配置 CREATE TABLE starrocks_sink (...) WITH ( ... 'sink.properties.merge_condition' = 'update_epoch > source.update_epoch' ); -- 写入执行 INSERT INTO starrocks_sink SELECT * FROM prepared_data; ``` --- #### 关键技术验证 1. **条件表达式有效性检查**: ```sql -- 在 StarRocks 中测试条件 SELECT * FROM your_target_table WHERE update_epoch > source.update_epoch LIMIT 1; ``` 若返回 `ERROR 1064 (HY000): Unknown column 'source.update_epoch'` → 确认列名拼写正确 2. **版本兼容性**: - StarRocks ≥ 2.4 才支持 `merge_condition` - 使用以下命令检查版本: ```sql SELECT CURRENT_VERSION(); ``` --- #### 预防措施 1. **表设计规范**: - 为需要条件更新的表预留数值型字段(如 `version BIGINT`) - 避免在主键模型中使用 `VARCHAR` 作为条件列 2. **写入监控**: ```bash # 查看 StarRocks FE 日志 tail -f /opt/starrocks/fe/log/fe.warn.log | grep 'merge_condition' ``` 3. **数据类型映射表**: | 使用场景 | 推荐类型 | 风险类型 | |-------------------|-------------|---------------| | 版本控制 | `BIGINT` | `VARCHAR` | | 时间戳比较 | `DATETIME` | `STRING` | | 状态标记 | `BOOLEAN` | `BITMAP` | > **重要提示**:该解决方案已在 StarRocks 2.5.3 + Flink 1.15 环境中验证[^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值