B4J Question B4j Class Destructor

Squiffy

Active Member
Licensed User
Longtime User
Is there any event called on a class when it is destroyed?

Specifically I have a class that creates a pooled DB handle. This class is instantiated from a server handler. Once the handler goes out of scope (and therefore, I assume, "destroyed" in the hands of the GC) the pool handle will survive if not manually released.

Of course I should release the handle myself, but I wanted to ensure that never got missed causing a leak.

This thread suggests no : https://www.b4x.com/android/forum/threads/classes-tutorial.18626/

but I though it worth asking as that's from 2012 and things might have changed.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Specifically I have a class that creates a pooled DB handle. This class is instantiated from a server handler. Once the handler goes out of scope (and therefore, I assume, "destroyed" in the hands of the GC) the pool handle will survive if not manually released.
Why are you creating a connection pool inside a handler? The whole purpose of the connection pool is to manage the connections for multiple handlers.
 
Upvote 0

Squiffy

Active Member
Licensed User
Longtime User
My terminology is wrong (or I'm making a mistake!) :

B4X:
Sub AppStart (Args() As String)

    Dim JdbcUrl As String = "jdbc:mysql://redacted"
    Dim DriverClass As String ="com.mysql.jdbc.Driver"
    Dim DBUser As String = "redacted"
    Dim DBPassword As String = "redacted"
   
    Try
        dbpool.Initialize(DriverClass,JdbcUrl,DBUser,DBPassword)

        'Dim jo As JavaObject = dbpool
        'jo.RunMethod("setCheckoutTimeout",Array As Object(5000))

    Catch
        Log("Failed to initialise DB Pool")
        Log(LastException)
        ExitApplication
    End Try

...


Then in my handler :

B4X:
    Try
        dbcon=Main.dbpool.GetConnection   
    Catch
        Log("Cannot get pooled DB connection")
        logFailedData
        Log(LastException)
    End Try

Is that wrong?
 
Upvote 0

Squiffy

Active Member
Licensed User
Longtime User
Firstly, thanks for confirming I'm using the pooling correctly. I wasn't 100% sure even though it seemed to work.

That is how I close the connection currently, I was just looking to see if there was a belt and braces way I could be sure it was cleared when the class got destroyed. I just like checking things are clean in one place like a destructor.

I suppose it's more curiosity than important.
 
Upvote 0

wonder

Expert
Licensed User
Longtime User
In my almost 3 years of B4x experience, I follow the following logic (I might be wrong):
- Any object/variable which was locally created ends-up destroyed/removed by the garbage collector if not returned or stored anywhere.

So... here's what I do:
- Create a non-local list / map / array / data-collection
- Create a local object
B4X:
Sub CreateObject
    Dim myObj as Object : myObj.Initialize
    globalObjectList.Add(myObj)
End Sub
- When I'm sure I don't need the object anymore, I just:
B4X:
Dim objIndex = globalObjectList.IndexOf(myObj) As Int
If objIndex = -1 Then Return False
globalObjectList.RemoveAt(objIndex)
Return True
This, to my understanding, marks the object for destruction, given it's no longer being used anywhere else.
 
Last edited:
Upvote 0

wonder

Expert
Licensed User
Longtime User
To be honest, I really prefer the way things work in C/C++.

I prefer being forced to use pointers and design my own memory management system, rather than trying to figure out what the hell is going under the hood in Java... :)

Java is like a horse: If you're a good rider, it can take you into amazing places at a relatively fast pace, thought lots of different terrain, in a relatively comfortable manner. The problem is, just like a horse, it has a mind of its own and might not always do what you expect it to do.

C is like a motorbike: When finely tuned, it can take you everywhere really fast, as long as you're driving on the right terrain type, with the right kind of fuel and you have made sure all you've tightened the little nuts and bolts in their right places. It takes patience but at least, it only does what you instructed it to do.
 
Last edited:
Upvote 0

wonder

Expert
Licensed User
Longtime User
As long as there are live references to an object then it will be kept alive.
Exactly. Using a list (of returned local objects) is just a way of making sure the object only exists (as a live reference) in that list and that once removed, there are no more live references anywhere else. In the end, it's just a form of control. :)

It was thanks to this method that I was able to have much more efficient memory management in my game engine:
https://www.b4x.com/android/forum/threads/project-kz2d-game-engine.60652/page-4#post-462309
90% reduction in memory usage! ;)

By the way, I'm using Maps, but the philosophy is the same.
 
Upvote 0

Squiffy

Active Member
Licensed User
Longtime User
Interesting read.
My original post though was not about the garbage collector, which I understand. It was about not forgetting to release resources like pool handles (my terminology). I like to put things like that in destructors (which I know now we don't have) or "close" events, to at least check everything is released. I often want to protect myself from myself, and recently I'd spent a while running out of db pool connections before I twigged they would never be automatically released....
 
Upvote 0

wonder

Expert
Licensed User
Longtime User
If you're a C/C++ programmer, using a Map to simulate the Heap really helps to keep things in order.
B4X:
Sub Globals
    Dim Heap as Map
End Sub

Sub CreateNewObject As Long
    'Simulate a 64-bit memory address
    Dim memoryAddress = DateTime.Now As Long
    'Create a local object
    Dim myObject As Object
    If Heap.IsInitialized = False Then Heap.Initialize
    Heap.Put(memoryAddress, myObject)
    Return memoryAddress
End Sub

Sub LaLaLa
    'Create, store and get a new object (C++ style)
    'Object *newObject = new Object;
    Dim newObject = Heap.Get(CreateNewObject)

    ' - or -
    Dim memoryAddress = CreateNewObject As Long
    Dim newObject = Heap.Get(memoryAddress)

    'Destroying
    Heap.Remove(memoryAddress)

    'The reference to newObject is deleted from the
    'Heap (map) and the local reference will be deleted
    'once you exit this Sub (LaLaLa). At this point, the
    'Garbage Collector will recognize that there are no
    'more live references to newObject and HOPEFULLY
    'do its job. ;)
End Sub
 
Upvote 0
Top