Zaplneni ramky   otázka

VB.NET, Databáze

Zdravim,

ve vb.net jsem si napsal takovou malou aplikaci pro monitoring pc, ktera pouze odesila nejake udaje na MSSQL.

Ale pri dlouhodobem (nekolikadenim) spustenim, se na pocitaci zaplni RAMka timto procesem. Mam to jenom pustene v casovaci cely program.

Tak me napadlo, jeste pred tim nez jsem vlozim kody, jestli neni nejakej obecnej problem co jsem neobjevil.

Diky moc Ruda

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Ne, to vzhledem ke Garbage Collectoru rozhodně není obecný problém. Už to, že máte celý program v události Timeru zavání problémy.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Tady je tedy hlavni program:

Imports System.Data.SqlClient
Imports System.Configuration
Imports System.DateTime
Imports System.Management

Module Module1
    Public LocalName As String
    Public DefaultConnectionString As String
    Public DefaultSqlConnection As New SqlClient.SqlConnection()

    Sub Main()
        'úvod do konzole
        Console.WriteLine("General Server Monitoring")
        Console.WriteLine()

        'nastavení hodnoty s jedinečným jménem serveru
        LocalName = CStr((EasyWmiFunction("Win32_ComputerSystem", "Domain") & "\" & (EasyWmiFunction("Win32_ComputerSystem", "Caption"))))

        'definice defaultního SQL spojení
        DefaultConnectionString = System.Configuration.ConfigurationManager.AppSettings("DefaultniDatabze")
        DefaultSqlConnection = New SqlClient.SqlConnection(DefaultConnectionString)

        'ověření existence, případně vytvoření záznamu tohoto serveru v databázi        
        Dim SqlCommandLocalServerExist As New SqlCommand("SELECT COUNT (Name) FROM [Servers] WHERE Name=@Name", DefaultSqlConnection)
        SqlCommandLocalServerExist.Parameters.AddWithValue("@Name", LocalName)
        DefaultSqlConnection.Open()
        Dim CountLocalName As Integer = SqlCommandLocalServerExist.ExecuteScalar()
        DefaultSqlConnection.Close()
        If CountLocalName = 0 Then
            Dim SqlCommandLocalServerCreate As New SqlCommand("INSERT INTO [Servers] ([Name]) VALUES (@Name)", DefaultSqlConnection)
            SqlCommandLocalServerCreate.Parameters.AddWithValue("@Name", LocalName)
            DefaultSqlConnection.Open()
            SqlCommandLocalServerCreate.ExecuteNonQuery()
            DefaultSqlConnection.Close()
        End If

        'zavedení LastSeen timeru a spuštění - 10 sec
        Dim LastSeenTimer As System.Timers.Timer
        LastSeenTimer = New System.Timers.Timer(10000)
        AddHandler LastSeenTimer.Elapsed, AddressOf OnLastSeenTimerEvent
        LastSeenTimer.Interval = 10000
        LastSeenTimer.Enabled = True
        OnLastSeenTimerEvent()

        'ověření existence záznamů jednotlivých disků a jejich případné vytvoření a smazání starých
        Dim SqlCommandDiskDeactive As New SqlCommand("UPDATE [Disks] SET [Active] = '0' WHERE [ServerName]=@ServerName", DefaultSqlConnection)
        SqlCommandDiskDeactive.Parameters.AddWithValue("@ServerName", LocalName)
        DefaultSqlConnection.Open()
        SqlCommandDiskDeactive.ExecuteNonQuery()
        DefaultSqlConnection.Close()

        Dim mngmtClass As ManagementClass = New ManagementClass("Win32_LogicalDisk")
        Dim mngmtObject As ManagementObject

        Dim SqlCommandDiskExist As New SqlCommand
        Dim SqlCommandDiskActive As New SqlCommand
        Dim SqlCommandDiskCreate As New SqlCommand
        Dim CountCurrentDisk As Integer

        For Each mngmtObject In mngmtClass.GetInstances()
            If mngmtObject("DriveType") = 3 Then
                SqlCommandDiskExist = New SqlCommand("SELECT COUNT (*) FROM [Disks] WHERE [Caption]=@Caption AND [ServerName]=@ServerName", DefaultSqlConnection)
                SqlCommandDiskExist.Parameters.AddWithValue("@Caption", mngmtObject("Caption"))
                SqlCommandDiskExist.Parameters.AddWithValue("@ServerName", LocalName)
                DefaultSqlConnection.Open()
                CountCurrentDisk = SqlCommandDiskExist.ExecuteScalar()
                DefaultSqlConnection.Close()
                If CountCurrentDisk = 0 Then
                    SqlCommandDiskCreate = New SqlCommand("INSERT INTO [Disks] ([ServerName], [Caption]) VALUES (@ServerName, @Caption)", DefaultSqlConnection)
                    SqlCommandDiskCreate.Parameters.AddWithValue("@ServerName", LocalName)
                    SqlCommandDiskCreate.Parameters.AddWithValue("@Caption", mngmtObject("Caption"))
                    DefaultSqlConnection.Open()
                    SqlCommandDiskCreate.ExecuteNonQuery()
                    DefaultSqlConnection.Close()
                End If
                SqlCommandDiskActive = New SqlCommand("UPDATE [Disks] SET [Active] = '1' WHERE [Caption]=@Caption AND [ServerName]=@ServerName", DefaultSqlConnection)
                SqlCommandDiskActive.Parameters.AddWithValue("@ServerName", LocalName)
                SqlCommandDiskActive.Parameters.AddWithValue("@Caption", mngmtObject("Caption"))

                DefaultSqlConnection.Open()
                SqlCommandDiskActive.ExecuteNonQuery()
                DefaultSqlConnection.Close()
            End If
        Next

        Dim SqlCommandDiskDeleteNoactive As New SqlCommand("DELETE FROM [Disks] WHERE [Active]='0'", DefaultSqlConnection)
        DefaultSqlConnection.Open()
        SqlCommandDiskDeleteNoactive.ExecuteNonQuery()
        DefaultSqlConnection.Close()



        'zavedení Disks timeru a spuštění - pro DEBUG 10 sec
        Dim DisksTimer As System.Timers.Timer
        DisksTimer = New System.Timers.Timer(10000)
        AddHandler DisksTimer.Elapsed, AddressOf OnDisksTimerEvent
        DisksTimer.Interval = 10000
        DisksTimer.Enabled = True
        OnDisksTimerEvent()



        Console.ReadKey()
    End Sub

    Sub OnLastSeenTimerEvent()
        Dim SqlCommandLastSeenUpdate As New SqlCommand("UPDATE [Servers] SET [LastSeen] = @LastSeen WHERE [Name] = @Name", DefaultSqlConnection)
        SqlCommandLastSeenUpdate.Parameters.AddWithValue("@Name", LocalName)
        SqlCommandLastSeenUpdate.Parameters.AddWithValue("@LastSeen", Now)
        DefaultSqlConnection.Open()
        SqlCommandLastSeenUpdate.ExecuteNonQuery()
        DefaultSqlConnection.Close()
    End Sub

    Sub OnDisksTimerEvent()
        Dim mngmtClass As ManagementClass = New ManagementClass("Win32_LogicalDisk")
        Dim mngmtObject As ManagementObject

        Dim SqlCommandDiskUpdate As New SqlCommand

        For Each mngmtObject In mngmtClass.GetInstances()
            If mngmtObject("DriveType") = 3 Then

                SqlCommandDiskUpdate = New SqlCommand("UPDATE [Disks] SET [Size]=@Size, [FreeSpace]=@FreeSpace WHERE [Caption]=@Caption AND [ServerName]=@ServerName", DefaultSqlConnection)
                SqlCommandDiskUpdate.Parameters.AddWithValue("@ServerName", LocalName)
                SqlCommandDiskUpdate.Parameters.AddWithValue("@Caption", mngmtObject("Caption"))
                SqlCommandDiskUpdate.Parameters.AddWithValue("@FreeSpace", Convert.ToInt64(mngmtObject("FreeSpace")))
                SqlCommandDiskUpdate.Parameters.AddWithValue("@Size", Convert.ToInt64(mngmtObject("Size")))

                DefaultSqlConnection.Open()
                SqlCommandDiskUpdate.ExecuteNonQuery()
                DefaultSqlConnection.Close()
            End If
        Next
    End Sub

End Module

A tady je pomocny modul:

Imports System.Management
Module EasyWMI
    '"Win32_ComputerSystem"

    Public Function EasyWmiFunction(ByVal currentClass As String, ByVal currentObject As String)
        Dim mngmtClass As ManagementClass = New ManagementClass(currentClass)
        Dim mngmtObject As ManagementObject

        For Each mngmtObject In mngmtClass.GetInstances()
            Return mngmtObject(currentObject)
        Next

    End Function



End Module

Dal projekt obsahuje jenom app.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="DefaultniDatabze" value="Server=srv;Initial Catalog=testdb;Trusted_Connection=no;User ID=user;Password=1234;" />
  </appSettings>
</configuration>

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Nechce se mi to celé luštit, ale na první pohled vidím hlavní nedostatek - vůbec nepoužíváte Using...End Using, což je u věcí jako ADO.NET nebo WMI trestuhodné. Přidělejte to ke všemu, co implementuje IDisposable a zkuste zda k zaplňování paměti dochází dál.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Zkusim a dam vedet, diky!

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback