fix: memory leaks

This commit is contained in:
hstyi
2025-02-20 17:13:37 +08:00
committed by hstyi
parent 0000e4610a
commit 604e07b43a
3 changed files with 58 additions and 49 deletions

View File

@@ -0,0 +1,42 @@
package app.termora.terminal.panel.vw
import app.termora.Disposable
import kotlinx.coroutines.*
import org.slf4j.LoggerFactory
import javax.swing.JPanel
import kotlin.time.Duration.Companion.milliseconds
abstract class AutoRefreshPanel : JPanel(), Disposable {
companion object {
private val log = LoggerFactory.getLogger(AutoRefreshPanel::class.java)
}
protected val coroutineScope = CoroutineScope(Dispatchers.IO)
protected abstract suspend fun refresh(isFirst: Boolean)
init {
coroutineScope.launch {
var isFirst = true
while (coroutineScope.isActive) {
try {
refresh(isFirst)
isFirst = false
} catch (e: Exception) {
if (log.isErrorEnabled) {
log.error(e.message, e)
}
if (isFirst) {
break
}
} finally {
delay(1000.milliseconds)
}
}
}
}
override fun dispose() {
coroutineScope.cancel()
}
}

View File

@@ -1,14 +1,13 @@
package app.termora.terminal.panel.vw
import app.termora.I18n
import app.termora.Icons
import app.termora.SSHTerminalTab
import app.termora.SshClients
import app.termora.*
import com.formdev.flatlaf.extras.FlatSVGIcon
import com.jgoodies.forms.builder.FormBuilder
import com.jgoodies.forms.layout.FormLayout
import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.swing.Swing
import kotlinx.coroutines.withContext
import org.apache.commons.lang3.StringUtils
import org.jdesktop.swingx.JXBusyLabel
import org.slf4j.LoggerFactory
@@ -22,7 +21,6 @@ import java.io.StringReader
import javax.swing.*
import javax.xml.parsers.DocumentBuilderFactory
import javax.xml.xpath.XPathFactory
import kotlin.time.Duration.Companion.milliseconds
class NvidiaSMIVisualWindow(tab: SSHTerminalTab, visualWindowManager: VisualWindowManager) :
SSHVisualWindow(tab, "NVIDIA-SMI", visualWindowManager) {
@@ -79,6 +77,8 @@ class NvidiaSMIVisualWindow(tab: SSHTerminalTab, visualWindowManager: VisualWind
percentageBtn.icon = if (isPercentage) Icons.text else Icons.percentage
nvidiaSMIPanel.refreshPanel()
}
Disposer.register(this, nvidiaSMIPanel)
}
private data class GPU(
@@ -183,8 +183,7 @@ class NvidiaSMIVisualWindow(tab: SSHTerminalTab, visualWindowManager: VisualWind
}
}
private inner class NvidiaSMIPanel : JPanel(BorderLayout()) {
private val coroutineScope = CoroutineScope(Dispatchers.IO)
private inner class NvidiaSMIPanel : AutoRefreshPanel() {
private val xPath by lazy { XPathFactory.newInstance().newXPath() }
private val db by lazy {
@@ -224,6 +223,8 @@ class NvidiaSMIVisualWindow(tab: SSHTerminalTab, visualWindowManager: VisualWind
private fun initViews() {
layout = BorderLayout()
add(
FormBuilder.create().debug(false)
.layout(
@@ -253,27 +254,11 @@ class NvidiaSMIVisualWindow(tab: SSHTerminalTab, visualWindowManager: VisualWind
private fun initEvents() {
coroutineScope.launch {
// 首次刷新
refresh(true)
while (coroutineScope.isActive) {
delay(1000.milliseconds)
try {
refresh()
} catch (e: Exception) {
if (log.isErrorEnabled) {
log.error(e.message, e)
}
}
}
}
}
private suspend fun refresh(isFirst: Boolean = false) {
override suspend fun refresh(isFirst: Boolean) {
val session = tab.getData(SSHTerminalTab.SSHSession) ?: return
val doc = try {
@@ -347,7 +332,6 @@ class NvidiaSMIVisualWindow(tab: SSHTerminalTab, visualWindowManager: VisualWind
refreshPanel()
}
}
private fun initPanel() {

View File

@@ -3,8 +3,9 @@ package app.termora.terminal.panel.vw
import app.termora.*
import com.jgoodies.forms.builder.FormBuilder
import com.jgoodies.forms.layout.FormLayout
import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.swing.Swing
import kotlinx.coroutines.withContext
import org.apache.commons.lang3.StringUtils
import org.apache.sshd.client.session.ClientSession
import org.slf4j.LoggerFactory
@@ -12,7 +13,6 @@ import java.awt.BorderLayout
import javax.swing.*
import javax.swing.table.DefaultTableCellRenderer
import javax.swing.table.DefaultTableModel
import kotlin.time.Duration.Companion.milliseconds
class SystemInformationVisualWindow(tab: SSHTerminalTab, visualWindowManager: VisualWindowManager) :
@@ -40,9 +40,8 @@ class SystemInformationVisualWindow(tab: SSHTerminalTab, visualWindowManager: Vi
Disposer.register(this, systemInformationPanel)
}
private inner class SystemInformationPanel : JPanel(BorderLayout()), Disposable {
private inner class SystemInformationPanel : AutoRefreshPanel() {
private val coroutineScope = CoroutineScope(Dispatchers.IO)
private val cpuProgressBar = SmartProgressBar()
private val memoryProgressBar = SmartProgressBar()
@@ -63,6 +62,7 @@ class SystemInformationVisualWindow(tab: SSHTerminalTab, visualWindowManager: Vi
private fun initViews() {
layout = BorderLayout()
add(createPanel(), BorderLayout.CENTER)
}
@@ -109,22 +109,10 @@ class SystemInformationVisualWindow(tab: SSHTerminalTab, visualWindowManager: Vi
}
private fun initEvents() {
coroutineScope.launch {
while (coroutineScope.isActive) {
try {
refresh()
} catch (e: Exception) {
if (log.isErrorEnabled) {
log.error(e.message, e)
}
} finally {
delay(1000.milliseconds)
}
}
}
}
private suspend fun refresh() {
override suspend fun refresh(isFirst: Boolean) {
val session = tab.getData(SSHTerminalTab.SSHSession) ?: return
try {
@@ -144,7 +132,6 @@ class SystemInformationVisualWindow(tab: SSHTerminalTab, visualWindowManager: Vi
log.error("refreshDisk", e)
}
}
}
private suspend fun refreshCPUAndMem(session: ClientSession) {
@@ -290,10 +277,6 @@ class SystemInformationVisualWindow(tab: SSHTerminalTab, visualWindowManager: Vi
}
}
override fun dispose() {
coroutineScope.cancel()
}
}
private data class Mem(