Not necessarily an indicator of bad code, but probably more of an indicator of code that can be optimized.
The job of the garbage collector is to free up memory that is no longer used so it can be re-used. Every time an object is instantiated using the New keyword, a block of memory is allocated. When there are no more variables referencing that object, it is the job of the GC to find it and release the memory
Consider an example of a timer tick that is setup to occur 50 times per second. In that event handler let's say there is an object that is created with a variable that is local to the event handler subroutine:
Private Sub .........
Dim MyObject as New Object
End Sub
Since the variable is declared within the subroutine, it's lifetime is over when the sub is exited. This results in the object no longer being referenced and waiting for the GC to find it for releasing the memory. This means every second, there are 50 blocks of memory being allocated, then marked for being released. The GC must keep up with these freeing up these instances that are no longer being used at a rate of 50 per second.
To optimize the code, we can consider keeping the object alive in memory and re-using it instead of creating a new one every time. Modifying the code above:
Private MyObject as Object
Private Sub .........
if MyObject Is Nothing then
MyObject = New Object
end if
End Sub
The variable pointing to the object is now moved out of the sub and becomes a variable with a class level scope. The object instance (block of memory) will no longer lose its reference when the subroutine is exited. So now we allocated the block of memory once and it will exist for the life of the class instead of the life of the subroutine. So now the GC does much less work.