Main Site Documentation

Why does ManagedThreadId changes after Debug.GC(false)?


#1

Hi:
I am building a program with several threads, and have been seeing strange things. So I isolated the strangeness to the following code which can run as a complete program and demonstrates what is happening.

I spin a new thread, with a sleep function, then print the time and thread ID. After 10 cycles I call debug.gc(false), and the thread ID changes back to the main thread. Is this a known behavior, by design, or a bug?

The reason I am doing this is because the larger program sometimes shows signs of a memory leak, and I wanted to use this as a tool to debug.

First the code, then the printout:

Imports GT = Gadgeteer
Imports GTM = Gadgeteer.Modules
Imports Gadgeteer.Modules.GHIElectronics


Namespace GadgeteerApp2
    Partial Public Class Program

        Public Sub ProgramStarted()
            Debug.Print("Program Started on managed thread id " & Thread.CurrentThread.ManagedThreadId.ToString)
            Dim ClockThread As New Thread(AddressOf PostTimeThread)
            ClockThread.Start()

        End Sub
        Dim i As Integer = 0
        Private Sub PostTimeThread()
            Do While True
                PostTime1()
                Thread.Sleep(999)
                i += 1
                If i = 10 Then Debug.GC(False)
            Loop
        End Sub

        Private Sub PostTime1()
            Dim s As String = i.ToString & ": " & DateTime.Now.ToString
            Do While s.Length < 20
                s = s & " "
            Loop
            '         display.WriteHere(s, 0, 0)   'works a few times then corrupts the diaplay and freezes the Raptor
            s = s & ", on managed thread " & Thread.CurrentThread.ManagedThreadId
            Debug.Print(s)
        End Sub
    End Class
End Namespace


Using mainboard GHI Electronics FEZRaptor version 1.0
Program Started on managed thread id 0
0: 06/01/2011 00:21:40, on managed thread 4
1: 06/01/2011 00:21:41, on managed thread 4
2: 06/01/2011 00:21:42, on managed thread 4
3: 06/01/2011 00:21:43, on managed thread 4
4: 06/01/2011 00:21:44, on managed thread 4
5: 06/01/2011 00:21:45, on managed thread 4
6: 06/01/2011 00:21:46, on managed thread 4
7: 06/01/2011 00:21:47, on managed thread 4
8: 06/01/2011 00:21:48, on managed thread 4
9: 06/01/2011 00:21:49, on managed thread 4
GC: 1msec 275736 bytes used, 66830028 bytes available
Type 0F (STRING              ):    948 bytes
Type 11 (CLASS               ):  10140 bytes
Type 12 (VALUETYPE           ):   1056 bytes
Type 13 (SZARRAY             ):   3780 bytes
  Type 03 (U1                  ):    156 bytes
  Type 04 (CHAR                ):    876 bytes
  Type 07 (I4                  ):   1332 bytes
  Type 0F (STRING              ):     48 bytes
  Type 11 (CLASS               ):   1368 bytes
Type 15 (FREEBLOCK           ): 66830028 bytes
Type 16 (CACHEDBLOCK         ):     72 bytes
Type 17 (ASSEMBLY            ):  29544 bytes
Type 18 (WEAKCLASS           ):     96 bytes
Type 19 (REFLECTION          ):    168 bytes
Type 1B (DELEGATE_HEAD       ):    360 bytes
Type 1D (OBJECT_TO_EVENT     ):    168 bytes
Type 1E (BINARY_BLOB_HEAD    ): 223140 bytes
Type 1F (THREAD              ):   1152 bytes
Type 20 (SUBTHREAD           ):     96 bytes
Type 21 (STACK_FRAME         ):   1632 bytes
Type 26 (WAIT_FOR_OBJECT_HEAD):     48 bytes
Type 27 (FINALIZER_HEAD      ):     72 bytes
Type 31 (IO_PORT             ):    108 bytes
Type 34 (APPDOMAIN_HEAD      ):     72 bytes
Type 36 (APPDOMAIN_ASSEMBLY  ):   3084 bytes
10: 06/01/2011 00:21:50, on managed thread 0
11: 06/01/2011 00:21:51, on managed thread 0
12: 06/01/2011 00:21:52, on managed thread 0
13: 06/01/2011 00:21:53, on managed thread 0
14: 06/01/2011 00:21:54, on managed thread 0
15: 06/01/2011 00:21:55, on managed thread 0
16: 06/01/2011 00:21:56, on managed thread 0



#2

Not quite sure why thread ID changes, but there one thing. Once you leave the PrgramStarted() function, ClockThread variable is no longer referenced, thus GC should collect it. I suggest declaring ClockThread at class level, so the pointer is not garbage collected.


#3

Thanks Simon!
That suggestion was right on and solved the problem.
Rocky