B4J Question [Solved] How to free memory after use?

behnam_tr

Active Member
Licensed User
Longtime User
Hi
I have a class and inside it I have a TableView with about 100 textboxes and comboboxes loaded.
When running the program for first time, the amount of RAM consumed is about 200 MB
After opening and closing the form several times or scrolling the tableview, the amount of memory consumption reaches 1 GB, but after closing the form, this space is not released.

**All data is read from the database, then stored in the map, then entered into the textboxes and comboboxes

1. How can I manually unload all the variables to free up the used space??
2. Why are they not deleted automatically after closing the form?؟
 
Solution
I'm not convinced that there is a problem so difficult to give solution. You can limit the JVM max heap size if you like.

kimstudio

Active Member
Licensed User
Longtime User
After opening and closing the form several times or scrolling the tableview, the amount of memory consumption reaches 1 GB
I would first check the source code again to see whether there are any hidden bugs there causing this memory behavior.
 
Upvote 0

behnam_tr

Active Member
Licensed User
Longtime User
The explanations were complete
Thank you, I got the answer

But in Java, the programmer need not care for all those objects which are no longer in use. Garbage collector destroys these objects. The main objective of Garbage Collector is to free heap memory by destroying unreachable objects. The garbage collector is the best example of the Daemon thread as it is always running in the background.

Ways to make an object eligible for Garbage Collector​

  • Even though the programmer is not responsible for destroying useless objects but it is highly recommended to make an object unreachable(thus eligible for GC) if it is no longer required.
  • There are generally four ways to make an object eligible for garbage collection.
    1. Nullifying the reference variable
    2. Re-assigning the reference variable
    3. An object created inside the method
    4. Island of Isolation
 
Upvote 0

emexes

Expert
Licensed User
all combobox have a same text (like country list)

I had an idea - to have all the comboboxes work from one single list, rather than have 500-100 duplicate lists - but I don't think it's going to work.

A spreadsheet-like editable 2d table might be the way to go, if you can find one that does the essentials of your wishlist.

I sense that others are already posting their own ideas to this thread too, so I'm expecting to experience some duh-why-didn't-I-think-of-that? moments real soon now.

?
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
I had an idea - to have all the comboboxes work from one single list, rather than have 500-100 duplicate lists - but I don't think it's going to work.
Sorry to say but this is a very bad idea. You will save about 500 bytes. Maybe 1/1M of a single image.

This thread goes deep into the preoptimization field. The correct thing to do with this thread is to ignore it until the OP posts a stack trace with an out of memory exception.
 
Upvote 0

behnam_tr

Active Member
Licensed User
Longtime User
Conclusion :
1- When free RAM memory is available, your program will consume it without removing the previous resources

2- When the amount of memory is limited by the command #VirtualMachineArgs: -Xms300m -Xmx300m, I think the old resources will be deleted and new resources will be replaced.Garbage Collection automatically deletes previous resources when RAM is not available or used more than 300mb.

3 - Garbage Collection automatically deletes previous resources when RAM is not available.

4 - I manually emptied the resources from within the program, but it had no effect.
B4X:
Sub frm_Closed
    TableView1.Items.Clear
    frm.RootPane.RemoveAllNodes
End Sub


The best solution is not to touch and let it do its job!! ;);)


sample attached.
 

Attachments

  • memory test.zip
    11.6 KB · Views: 134
Last edited:
Upvote 0

emexes

Expert
Licensed User
I had an idea - to have all the comboboxes work from one single list, rather than have 500-100 duplicate lists - but I don't think it's going to work.
Sorry to say but this is a very bad idea. You will save about 500 bytes. Maybe 1/1M of a single image.

Well, I'm always up for a challenge, so I measured the saving for a TableView of 1000 rows each containing a ComboBox of a List of 200 Strings of 20 Chars each.

The saving of (re)using one single List for all ComboBoxes, vs using 1000 distinct but identical Lists ie a new List (re)constructed for each ComboBox, is 12,582,912 bytes.

Divide that by 999 duplicate Lists not used, and divide again by 200 items per List, gives 63 bytes per list element, which had me a bit confused until I remembered that Chars are two bytes, not one. 63 bytes = 20 characters + 23 bytes of List and String housekeeping = sounds about right.


Also, I've often wondered how you get so much done, and I've finally worked it out. You're a time traveller, right?

500 bytes / (1/1M of a single image) = 500 MB image = 125 megapixels (uncompressed 10-11 bits/channel) = iPhone CXLIII eta 2174 ie 153 years from now.

Everything makes sense now. :cool:
 
Last edited:
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Well, I'm always up for a challenge, so I measured the saving for a TableView of 1000 rows each containing a ComboBox of a List of 200 Strings of 20 Chars each.
You forgot something, if the strings are the same in the duplicate lists then the same string instance will be used in all lists (in most cases).

B4X:
List1.Add("Some long string")
List2.Add("Some long string")
List3.Add("Some long string")
List4.Add("Some long string")
List5.Add("Some long string")
List6.Add("Some long string")
List7.Add("Some long string")
Memory needed = [memory of the long string] + 7 small pointers (please don't think too much the size of the 7 pointers. I will give you 28 bytes from my PC if needed).

500 MB ram for a single image is indeed a bit too much but a large image can consume quite a lot of memory. For example a 2000x2000 image will take about 16MB. Developers sometimes try to optimize these 28 bytes while a single image takes 571,428 times more ram.

The ONLY thing that small preoptimizations will do is to make your code more complex, more difficult to maintain and more difficult to optimize.
 
Upvote 0

emexes

Expert
Licensed User
You forgot something, if the strings are the same in the duplicate lists then the same string instance will be used in all lists (in most cases).

Not forgotten. I was working on the basis that each TableView row Combobox was being re-constructed from scratch, from a memory copy of data hopefully read only once from a database or file, but likely repeatedly run through cleansing functions each time eg .ToProperCase, .Trim, possibly even reparsed from a whole-file String each time.

I am pretty certain that Java's String subsystem doesn't have time to go looking for already-existing duplicates of new generated-on-the-fly Strings.


500 MB ram for a single image is indeed a bit too much but a large image can consume quite a lot of memory. For example a 2000x2000 image will take about 16MB. Developers sometimes try to optimize these 28 bytes while a single image takes 571,428 times more ram.

I'm not optimizing 28 bytes. And I didn't even think it'd work anyway. But turns out it does - I'm probably more surprised than you about this. And then the OP casually mentioned "I have maybe 10 forms" which ups the potential saving from 12 MB to 120 MB, cf plenty of new phones are 1 GB RAM, economy phones sometimes not even that.

Anyway, if the OP is happy with their current speed, than I'm with you, ie: no further effort required, except maybe some elbow stretches... ?
 
Last edited:
Upvote 0

kimstudio

Active Member
Licensed User
Longtime User
The best solution is not to touch and let it do its job!!
I test your test app and I am shocked by the same result you have:
After the tablview form shows, mem is 300M, it increases to 2G if just scrolls the vertical scrollbar up and down several times, and during scrolling, obvious delay happens. 5000 rows with some views like textview or combobox as cell is quite normal in applications. If this situation can't be solved, the tableview is almost useless.

With this line enabled: #VirtualMachineArgs: -Xms300m -Xmx300m
After several scrollbar up and down, I get this: java.lang.OutOfMemoryError: GC overhead limit exceeded

I don't understand why the form shows, ram 200-300M (at this time all the views of cells are already initialized and loaded), and then scrollbar operation only will make it to 2G.
 
Upvote 0

Magma

Expert
Licensed User
Longtime User
I test your test app and I am shocked by the same result you have:
After the tablview form shows, mem is 300M, it increases to 2G if just scrolls the vertical scrollbar up and down several times, and during scrolling, obvious delay happens. 5000 rows with some views like textview or combobox as cell is quite normal in applications. If this situation can't be solved, the tableview is almost useless.

With this line enabled: #VirtualMachineArgs: -Xms300m -Xmx300m
After several scrollbar up and down, I get this: java.lang.OutOfMemoryError: GC overhead limit exceeded

I don't understand why the form shows, ram 200-300M (at this time all the views of cells are already initialized and loaded), and then scrollbar operation only will make it to 2G.
...I remember the same problem at vb6... sorry.. not the same exact... don;t remember exactly... i think was gridview... had a limit of 32K lines...

...Well the solution for tableview... came with b4xtable - i think is perfect and using pagination...

but ofcourse is total different logic...
 
Upvote 0

Magma

Expert
Licensed User
Longtime User
Upvote 0

Mashiane

Expert
Licensed User
Longtime User
...Well the solution for tableview... came with b4xtable
I am with you on this one

before the b4xtable I was using the same approach the OP is using, and I had the same problems.

 
Upvote 0

kimstudio

Active Member
Licensed User
Longtime User
Regarding inline editing:

I am thinking a way to reduce the memory usage, is to not load each cell as a view, just plain string text, then when user clicks a cell, a textview or combobox view will appear to cover that cell that user can operate, then save the values in the tableview again. However, to realize this, the cell position and size should be obtained to place the new view on it, I think it is feasible but not trivial.
 
Upvote 1

chikega

Member
Licensed User
This book recently co-authored by my friend and colleague, Maaike van Putten, may prove useful:
"Java Memory Management" by Maaike van Putten | Sean Kennedy (2022 Packt Publishing)

Screenshot 2023-01-08 at 11.47.55 PM.png


Here's the Table of Contents for those that may be interested:

Table of Contents

Preface

1
Different Parts of the Java Memory

Technical requirements
Understanding computer memory and Java memory
Computer memory
Accessing the main memory
Overview of the main memory
Java memory and the JVM
The JVM
Memory management and the JVM
Memory management before Java
Understanding the JVM’s components for memory management
Runtime data area
Creating variables in Java
Primitives and reference types
Storing variables on the stack
Current frame and current method
Elements of the frame
Values on the stack
Primitives and wrapper classes
Creating objects in Java
Storing objects on the heap
Exploring the Metaspace
Summary

2
Primitives and Objects in Java Memory

Technical requirements
Understanding primitives on the stack and heap
Storing objects on the heap
References
Objects
Understanding the differences between references and objects
Managing object references and security
Inspecting the escaping references issue
Summary

3
Zooming in on the Heap Space

Exploring the different generations on the heap
Garbage collection roots
Learning how the spaces are used
Understanding the minor garbage collection algorithm
Demonstrating the minor garbage collection algorithm in action
Summary

4
Freeing Memory with Garbage Collection

Technical requirements
Being eligible for GC
Marking by the garbage collector
Stop-the-world
Reference counting and islands of isolation
Sweeping by the garbage collector
Normal sweeping
Sweeping with compacting
Sweeping with copying
Exploring GC implementations
Generational GC
Serial GC
Parallel GC
CMS GC
G1 GC
Z GC
Monitoring GC
Summary

5
Zooming in on the Metaspace

JVM usage of the Metaspace
Class loading
Releasing Metaspace memory
Metaspace runs out of memory
Metaspace size exceeds a JVM-set threshold
Garbage collection of the Metaspace
Summary

6
Configuring and Monitoring the Memory Management of the JVM

Technical requirements
The basics of JVM tuning for memory management
Obtaining relevant metrics for memory management
Well-functioning memory
Normal latency
Level of throughput
Profiling Java applications
Profiling with jstat and jmap
Profiling with VisualVM
Tuning the configurations of the JVM
Tuning the heap size and thread stack size
Logging low memory
Tuning the Metaspace
Garbage collection tuning

7
Avoiding Memory Leaks

Technical requirements
Understanding memory leaks
Spotting memory leaks
Heap memory footprint
Garbage collector activity
Heap dump
Avoiding memory leaks
Common pitfalls and how to avoid them
Summary


Java Memory Management
Maaike van Putten | Sean Kennedy
 
Upvote 0
Top