B4J Question Freeing up discarded nodes and views?

MegatenFreak

Active Member
Licensed User
Hi.
There is one page in my app which is used to statistics. It contains a table with 10+ columns and hundreds of rows. Now, to make some styling things happen, I don't just pass an array of strings as values to the table. Each table cell contains a pane, and that pane contains a node, which I can style as I want, individually.
So, a single execution of the search process that fills the table will result in creating around 1000 labels and panes. The creation alone doesn't seems to be anything heavy, but once I set them to the table, it occupies a lot of memory. Now, when the search is executed again, those 2000 views are clearly not released, because the memory load increases just like it did the first time. I was looking for a way to eliminate the panes and labels from one execution when another one happens. I understand that it Java has no "Free()" function like C does, and I can only rely on the Garbage Collector. However, I've tried the various solutions I've found around the web and have had no luck. I've tried setting all those nodes to NULL and trying to manually fire the GC, but to no avail. This way doing a few searches could easily cause an OOM.
Any pointers?
thanks a lot.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Sounds like you are not removing the views properly. Their memory will be freed once there are no more live references.

With that said, it is never a good idea to create thousands of views. The correct solution is to use virtualization / lazy loading. Many threads about it.

You can also use B4XTable which is page based and provides a useful search feature. You can customize it in many ways.
 
Upvote 0

MegatenFreak

Active Member
Licensed User
Thanks for the info. About "removing" the views, I always do this:
B4X:
TBL_Results.Items.Clear

This time, just to be thorough, I did this too: (each cell is a node, and that node contains a label)
B4X:
For i = 0 To TBL_Results.Items.Size - 1
            Dim row() As Object = TBL_Results.Items.Get(i)
            For k = 0 To row.Length - 1
                Dim n As Pane = row(k)
                Dim lab As Label = n.GetNode(0)
                lab = Null
                n = Null
                row(k) = Null
            Next
            TBL_Results.Items.Set(i, Null)
Next
TBL_Results.Items.Clear

What else can I do to remove those views?
 
Upvote 0

MegatenFreak

Active Member
Licensed User
Well, this is weird... To understand how this whole thing works, I ran a test on an empty project, just making nodes and trying to remove them and check memory usage. This is what happened:
When I remove the nodes immediately after creation, without giving the UI the chance to update itself, the memory is immediately released, all fine:
B4X:
For i = 0 To 5000
        Dim lb As Label
        lb.Initialize("")
        lb.Text = i
        Form2.RootPane.AddNode(lb, 50, 200, 300, 100)
Next
'Sleep(0)      'No UI update chance!
For Each n As Node In Form2.RootPane.GetAllViewsRecursive
        If n Is Label Then n.RemoveNodeFromParent
Next
But once I uncomment the Sleep line and allow the UI update, the nodes eat up memory without being released. Even though they are removed from the form, the memory won't be released. It's like once the UI updates, the labels are stuck in the memory. Setting them to NULL made no difference either.
I tried everything, and I just can't "remove" those labels from memory. What am I doing wrong???
Any help would be appreciated.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
I've just tested it with:
B4X:
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
    For n = 1 To 1000
        For i = 0 To 5000
            Dim lb As Label
            lb.Initialize("")
            lb.Text = i
            Root.AddView(lb, 50, 200, 300, 100)
        Next
        Sleep(0)   
        Root.RemoveAllViews
        Sleep(100)
    Next
End Sub
Test in release mode.

As expected the memory climbs at the beginning and then it stays more or less constant.
 
Upvote 0

MegatenFreak

Active Member
Licensed User
As expected the memory climbs at the beginning and then it stays more or less constant.
I tested that, and you're right. Though the memory goes up to 800MB, it doesn't rise any further.
So there is no way to just release everything and go back (at least close) to the initial 80 MB memory usage, right? I don't understand why Java is so memory-hungry.
Well at least it won't build up to an OOM and application crash. Thanks
 
Last edited:
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
o there is no way to just release everything and go back (at least close) to the initial 80 MB memory usage, right? I don't understand why Java is so memory-hungry.
Well at least it won't build up to an OOM and application crash. Thanks
Everything written here is incorrect.
Don't waste your time trying to "improve" the garbage collector work. It is a very sophisticated component, optimized by hundreds of engineers for many years.
If your app crashes because of memory issues then you have a real problem. It is not related to the GC behavior.
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…