小编Sam*_*Sam的帖子

CoroutineExceptionHandler 应该如何处理 OutOfMemoryError 或其他致命错误?

我正在实现一个自定义 Kotlin CoroutineScope,用于处理通过 WebSocket 连接接收、处理和响应消息。该作用域的生命周期与 WebSocket 会话相关,因此只要 WebSocket 打开,它就处于活动状态。作为协程作用域上下文的一部分,我安装了一个自定义异常处理程序,如果存在未处理的错误,该处理程序将关闭 WebSocket 会话。是这样的:

val handler = CoroutineExceptionHandler { _, exception -> 
    log.error("Closing WebSocket session due to an unhandled error", exception)
    session.close(POLICY_VIOLATION)
}
Run Code Online (Sandbox Code Playgroud)

我惊讶地发现异常处理程序不仅接收异常,而且实际上为所有未处理的可抛出对象(包括Error. 我不确定应该如何处理这些,因为我从Java API 文档Error中知道“一个Error[...] 表明合理的应用程序不应尝试捕获的严重问题”

我最近遇到的一个特殊情况是OutOfMemoryError由于会话处理的数据量所致。OutOfMemoryErrormy 收到了,这CoroutineExceptionHandler意味着它已被记录并且 WebSocket 会话已关闭,但应用程序继续运行。这让我感到不舒服,因为我知道OutOfMemoryError在代码执行期间的任何时候都可以抛出 an ,从而导致应用程序处于不可恢复的状态。

我的第一个问题是:为什么 Kotlin API 选择将这些错误传递给CoroutineExceptionHandler我(程序员)来处理?

我的第二个问题是:我处理它的适当方法是什么?我至少可以想到三个选择:

  1. 继续执行我现在正在执行的操作,即关闭引发错误的 WebSocket 会话,并希望应用程序的其余部分能够恢复。正如我所说,这让我感到不舒服,特别是当我阅读这样的答案时,这是针对有关OutOfMemoryError在 Java 中捕获的问题的回答,该问题强烈建议不要尝试从此类错误中恢复。
  2. 重新抛出错误,让它传播到线程。这就是我在遇到Error正常(或框架)代码的任何其他情况下通常会做的事情,因为它最终会导致 …

error-handling jvm out-of-memory kotlin kotlin-coroutines

5
推荐指数
1
解决办法
884
查看次数

将多个 ByteBuffer 读入单个字符串的节省空间的方法是什么?

我正在编写一个解码器,它将接收一系列字节缓冲区并将内容解码为单个String. 可以有任意数量的字节缓冲区,每个缓冲区包含任意数量的字节。缓冲区不一定在字符边界上分割,因此根据编码,它们可能在开头或结尾包含部分字符。这就是我想要做的,StringByteStreamDecoder我需要编写的新类在哪里。

suspend fun decode(data: Flow<ByteBuffer>, charset: Charset): String {
    val decoder = StringByteStreamDecoder(charset)
    data.collect { bytes ->
        decoder.feed(bytes)
    }
    decoder.endOfInput()
    return decoder.toString()
}
Run Code Online (Sandbox Code Playgroud)

尝试1

最简单的方法是将所有字节缓冲区收集到一个字节数组中。我拒绝了这种方法,因为它具有显着的内存开销。它需要为完整消息分配空间至少两次:一次为原始字节,一次为解码字符。这是我的简单实现,使用 aByteArrayOutputStream作为扩展字节缓冲区。

class StringByteStreamDecoder(private val charset: Charset) {
    private val buffer = ByteArrayOutputStream()

    fun feed(data: ByteBuffer) {
        if (data.hasArray()) {
            buffer.write(data.array(), data.position() + data.arrayOffset(), data.remaining())
        } else {
            val array = ByteArray(data.remaining())
            data.get(array)
            buffer.write(array, 0, array.size)
        }
    }

    fun endOfInput() {
        buffer.flush()
    }

    override fun toString(): String {
        return …
Run Code Online (Sandbox Code Playgroud)

nio bytebuffer nonblocking kotlin kotlin-flow

5
推荐指数
1
解决办法
1022
查看次数

PHP数组的笛卡尔积

标题可能会产生误导,但我真的不知道它叫什么.我对此感到抱歉 :(

所以,我有一个像这样的数组

$start = array(
    array('waterpark'),
    array('spain','greece'),
    array('1','2','3','4'),
);
Run Code Online (Sandbox Code Playgroud)

我如何将该数组转换为这样

$output = array(
    array('waterpark', 'spain', '1'),
    array('waterpark', 'spain', '2'),
    array('waterpark', 'spain', '3'),
    array('waterpark', 'spain', '4'),
    array('waterpark', 'greece', '1'),
    array('waterpark', 'greece', '2'),
    array('waterpark', 'greece', '3'),
    array('waterpark', 'greece', '4'),
);
Run Code Online (Sandbox Code Playgroud)

先感谢您

php arrays

3
推荐指数
1
解决办法
1562
查看次数

Kotlin 中的 Gradle 构建系统是什么?

我在阅读 Kotlin 文档时发现了这样的说法: 默认情况下,您的项目将使用 Gradle 构建系统和 Kotlin DSL。 这是什么意思?我在 IntelliJ 中创建新项目时看到了 Gradle Kotlin 选项: IntelliJ项目配置截图

有人可以向我解释一下这些,以及作为初学者我应该使用哪个捆绑包吗?

kotlin

1
推荐指数
1
解决办法
661
查看次数

不是一个句子(Compiler Error Java/Android)

我正在尝试做一个简单的if语句使用?图案.导致"不是声明" - 错误.有人可以向我解释为什么使用正常的if语句不会发生这种情况?

错误:

cursor.isNull(0) ? insert_SQL_RSServer.bindNull(0) : insert_SQL_RSServer.bindLong(0, cursor.getLong(0)); // id
Run Code Online (Sandbox Code Playgroud)

没错误:

if(cursor.isNull(0))
    insert_SQL_RSServer.bindNull(0);
else
    insert_SQL_RSServer.bindLong(0, cursor.getLong(0));
Run Code Online (Sandbox Code Playgroud)

这是完全相同的行为....

java android compiler-errors

0
推荐指数
1
解决办法
64
查看次数