From 65afed54892126faf5aeed80d6245eb3a5dabfab Mon Sep 17 00:00:00 2001 From: justinlei Date: Mon, 20 Nov 2023 15:07:24 +0800 Subject: [PATCH] optimize memory leak --- cloudphone/src/main/cpp/CasController.cpp | 9 +++++++++ cloudphone/src/main/cpp/CasJniBridge.cpp | 4 ++-- cloudphone/src/main/cpp/CasOpusBridge.cpp | 12 +++++++++--- .../src/main/cpp/cas_service/CasHeartbeatThread.cpp | 13 ++++++++++++- .../huawei/cloudphone/apiimpl/CloudPhoneImpl.java | 4 +++- .../com/huawei/cloudphone/service/CasProcessor.java | 4 ++-- 6 files changed, 37 insertions(+), 9 deletions(-) diff --git a/cloudphone/src/main/cpp/CasController.cpp b/cloudphone/src/main/cpp/CasController.cpp index 135df22..98aae1b 100644 --- a/cloudphone/src/main/cpp/CasController.cpp +++ b/cloudphone/src/main/cpp/CasController.cpp @@ -787,6 +787,10 @@ int CasController::JniRecvData(CasMsgType type, uint8_t *data, int length) if ((unsigned int)length < dataLen) { ERR("Input buffer is not large enough, type %d free %d payload %u", streamMsgHead->type, length, dataLen); + if (pPkt != nullptr) { + free(pPkt); + pPkt = nullptr; + } return 0; } @@ -798,6 +802,11 @@ int CasController::JniRecvData(CasMsgType type, uint8_t *data, int length) IsNeedRotation((int) (*pPayload)); } + if (pPkt != nullptr) { + free(pPkt); + pPkt = nullptr; + } + return dataLen; } diff --git a/cloudphone/src/main/cpp/CasJniBridge.cpp b/cloudphone/src/main/cpp/CasJniBridge.cpp index 94faf44..939c953 100644 --- a/cloudphone/src/main/cpp/CasJniBridge.cpp +++ b/cloudphone/src/main/cpp/CasJniBridge.cpp @@ -165,14 +165,14 @@ extern "C" JNIEXPORT jint JNICALL JNI(recvData)(JNIEnv *env, jclass, jbyte type, { uint8_t *data = (uint8_t *)env->GetByteArrayElements(jData, nullptr); int ret = gJniApiCtrl->JniRecvData((CasMsgType)type, data, length); - env->ReleaseByteArrayElements(jData, (jbyte *)data, JNI_COMMIT); + env->ReleaseByteArrayElements(jData, (jbyte *)data, JNI_ABORT); return ret; } extern "C" JNIEXPORT jint JNICALL JNI(sendData)(JNIEnv *env, jclass clazz, jbyte type, jbyteArray jData, jint length) { uint8_t *data = (uint8_t *)env->GetByteArrayElements(jData, nullptr); int ret = gJniApiCtrl->JniSendData((CasMsgType)type, data, length); - env->ReleaseByteArrayElements(jData, (jbyte *)data, JNI_COMMIT); + env->ReleaseByteArrayElements(jData, (jbyte *)data, JNI_ABORT); return ret; } diff --git a/cloudphone/src/main/cpp/CasOpusBridge.cpp b/cloudphone/src/main/cpp/CasOpusBridge.cpp index 1f6f840..5bde409 100644 --- a/cloudphone/src/main/cpp/CasOpusBridge.cpp +++ b/cloudphone/src/main/cpp/CasOpusBridge.cpp @@ -78,21 +78,27 @@ extern "C" JNIEXPORT jint JNICALL Java_com_huawei_cloudphone_jniwrapper_OpusJNIW return JNI_ERR; } + jbyte *decodeInputData = inputData; + jshort *decodeOutputData = outputData; + int outLen = 0; while (inputBufferLen > 0) { int bytes = inputBufferLen; int decodeLen = - opus_decode(decoderPtr, (unsigned char *)inputData, bytes, (opus_int16 *)outputData, FRAME_SIZE, 0); + opus_decode(decoderPtr, (unsigned char *)decodeInputData, bytes, (opus_int16 *)decodeOutputData, FRAME_SIZE, 0); if (decodeLen != FRAME_SIZE) { ERR("Opus decode error decoder len %d.", decodeLen); return JNI_ERR; } outLen += FRAME_SIZE * CHANNELS; - inputData += bytes + SHORT_SIZE; - outputData += FRAME_SIZE * CHANNELS; + decodeInputData += bytes + SHORT_SIZE; + decodeOutputData += FRAME_SIZE * CHANNELS; inputBufferLen -= bytes + SHORT_SIZE; } + env->ReleaseByteArrayElements(inputBuffer, (jbyte *)inputData, JNI_ABORT); + env->ReleaseShortArrayElements(outputBuffer, (jshort *)outputData, JNI_ABORT); + return (jint)(outLen); } diff --git a/cloudphone/src/main/cpp/cas_service/CasHeartbeatThread.cpp b/cloudphone/src/main/cpp/cas_service/CasHeartbeatThread.cpp index ae0167f..2f5409d 100644 --- a/cloudphone/src/main/cpp/cas_service/CasHeartbeatThread.cpp +++ b/cloudphone/src/main/cpp/cas_service/CasHeartbeatThread.cpp @@ -46,6 +46,9 @@ uint64_t CasHeartbeatThread::GetLag() uint64_t CasHeartbeatThread::TestLag() { + if (this->m_threadStatus == CAS_THREAD_EXIT) { + return 0; + } struct timeval sent, recv; const int sleepTime = 20000; gettimeofday(&sent, nullptr); @@ -55,7 +58,7 @@ uint64_t CasHeartbeatThread::TestLag() gettimeofday(&recv, nullptr); if (!ret) { m_sendHbErrCount++; - if (m_sendHbErrCount >= 5) { + if (m_sendHbErrCount >= 5 && m_casSocket != nullptr) { INFO("Send or recv heartbeat failed."); m_casSocket->SetStatus(SOCKET_STATUS_DISCONNECT); } @@ -69,6 +72,9 @@ uint64_t CasHeartbeatThread::TestLag() void CasHeartbeatThread::UpdateLag(uint64_t lag) { + if (this->m_threadStatus == CAS_THREAD_EXIT) { + return; + } if (m_lagDeque.size() >= MAX_LAGS_NUM) { m_lagDeque.pop_front(); } @@ -157,7 +163,12 @@ int CasHeartbeatThread::Exit() if (this->m_threadStatus != CAS_THREAD_EXIT) { this->m_threadStatus = CAS_THREAD_EXIT; } + int waitCount = 0; while (this->m_threadStatus == CAS_THREAD_EXIT) { + if (waitCount >= 2) { + break; + } + waitCount++; usleep(1000); } return 0; diff --git a/cloudphone/src/main/java/com/huawei/cloudphone/apiimpl/CloudPhoneImpl.java b/cloudphone/src/main/java/com/huawei/cloudphone/apiimpl/CloudPhoneImpl.java index cfafdee..350d53e 100644 --- a/cloudphone/src/main/java/com/huawei/cloudphone/apiimpl/CloudPhoneImpl.java +++ b/cloudphone/src/main/java/com/huawei/cloudphone/apiimpl/CloudPhoneImpl.java @@ -908,7 +908,9 @@ public class CloudPhoneImpl implements ICloudPhone { } } try { - Thread.sleep(100); + if (!Thread.interrupted()) { + Thread.sleep(100); + } } catch (InterruptedException e) { CASLog.e(TAG, "check connect state failed. " + e.getMessage()); } diff --git a/cloudphone/src/main/java/com/huawei/cloudphone/service/CasProcessor.java b/cloudphone/src/main/java/com/huawei/cloudphone/service/CasProcessor.java index eae0a3e..1185123 100644 --- a/cloudphone/src/main/java/com/huawei/cloudphone/service/CasProcessor.java +++ b/cloudphone/src/main/java/com/huawei/cloudphone/service/CasProcessor.java @@ -214,10 +214,10 @@ public class CasProcessor { mUpstreamReceiveDispatcher.deleteNewPacketCallback((byte) JNIWrapper.CHANNEL); mUpstreamReceiveDispatcher.deleteNewPacketCallback((byte) JNIWrapper.VIRTUAL_DEVICE_DATA); mUpstreamReceiveDispatcher.deleteNewPacketCallback((byte) JNIWrapper.IMEDATA); - mAudioTrackerCallback.closeAudioTrack(); - mAudioTrackerCallback = null; mUpstreamReceiveDispatcher.stopBlocked(); mUpstreamReceiveDispatcher = null; + mAudioTrackerCallback.closeAudioTrack(); + mAudioTrackerCallback = null; } } -- Gitee