mirror of
https://github.com/TermoraDev/termora.git
synced 2026-01-16 02:12:58 +08:00
fix: memory leaks
This commit is contained in:
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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() {
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user