23
Well some time ago, when I took some classes J2ME to Mobile (almost deceased ), where I was presented to a concept of scope hitherto unknown by me, that would be:
{
// cria um novo escopo
}
Where anywhere a method is possible to force new scopes. Searching I found some sources and references that may be the article Thinking in Java on the website Linuxtopia and this other issue of Stackoverflow.
So seeking to optimize some features in my Android applications, I thought of refactoring my codes to take advantage of this form of resource management, only that I have no knowledge if it really can make a difference.
Then I present the following example, to contextualize my doubt:
Example:
Suppose I have one class
large that allocates many resources while being initialized:
public class ClasseGrande{
// ...
public void alocaMuitosRecursos(){
// Aqui inicia varios atributos da ClasseGrande()
// ...
}
public String obtemResultado(){
return "Resultado da classe grande";
}
}
And the following 3 approaches to use:
Approach 1 (My current):
// tudo no mesmo scope
public void testScopeMethod1(){
ClasseGrande classeGrande = new ClasseGrande();
classeGrande.alocaMuitosRecursos();
// ... usar a classe grande
String resultado = classeGrande.obtemResultado();
// agora não se utiliza mais a classe grande só se manipula seu resultado
// faz vários processos com o atributo resultado
// ...
// termina método, e só aqui todos os recursos são liberados para GC. Certo?
}
Approach 2 (using methods for dividing scopes):
// utiliza método para trocar de scope
public void testScopeMethod2(){
String resultado = processaClasseGrande();
// faz vários processos com o atributo resultado
// ...
// termina método, e libera os recursos do método testScopeMethod2
}
private String processaClasseGrande(){
ClasseGrande classeGrande = new ClasseGrande();
classeGrande.alocaMuitosRecursos();
// ... usar a classe grande
return classeGrande.obtemResultado();
// aqui a classe grande já é liberada, pois finalizou-se seu escopo de método. Certo?
}
Approach 3 (using sub-scopes within the method itself, right after using the resource):
// com sub scope no método
public void testScopeMethod3(){
String resultado;
{
ClasseGrande classeGrande = new ClasseGrande();
classeGrande.alocaMuitosRecursos();
// ... usar a classe grande
resultado = classeGrande.obtemResultado();
// aqui a classe grande já é liberada, pois finalizou-se seu escopo. Certo?
}
// agora não se utiliza mais a classe grande só se manipula seu resultado
// faz vários processos com o atributo resultado
// ...
// termina método, e libera os recursos do método testScopeMethod, mas a classe grande já foi libera logo após ser utilizada. Certo?
}
Questions:
- Does it really make a difference in performance? Why?
- If it makes a difference, approaches 2 and 3 present differences of performance? Where and why?
- If it makes any sense, it would be good practice to keep this in mind for robust designs, mainly thinking of devices mobile?
Fernando, could you check on Memory Monitor from Android Studio, along with a call to Garbage Collector, but if the processing done until the reference loss (in case 1) is small, there will be no difference in the scope change. You can also assign
null
to the reference, to try to release soon the large object (calling the GC later).– Wakim
@Wakim, you say make explicit calls to the Garbage Collector (
System.gc()
)? Because that my doubt would be not only for robust methods, but to always try to go this way, trying to minimize the resources to each part of the application, thus seeking a more efficient and optimized result, and the idea of scope seems to me a cleaner and more readable way to do this, compared to setarnull
and explicitly call the GC. But I do not rule out the possibility if it is to get better optimization of resources, because today I am facing serious problems ofOutOfMemory
on my app.– Fernando Leal
@Wakim, and regarding your tip to use Memory Monitor from Android Studio, I will try to create a test case here and see the results. Thanks for the tip. = D
– Fernando Leal
Yes, it would be the call to
System.gc
, but it does not guarantee that it will run on time, it scalona an execution.OutOfMemory
may be a sign of Memoryleaks, recently the Square released a tool that helps analyze their existence, called Leakcanary, maybe it’s worth analyzing if there’s no such problem in your app. Something else could be usingObject Pools
, to reduce the amount of objects created, take a look at this video from Colt Mcanlis to understand.– Wakim
Actually using scopes is more "beautiful" than setting null and calling GC, but it would suit cases where you allocate large quantities, and at specific points, not by the whole code. Perhaps this is the case to use the
largeHeap
in hisAndroidManifest
.– Wakim
@Wakim, I will review your tips especially regarding the Leakcanary, which from what I’ve seen can help identify what’s causing the Memoryleak in the application. And the
largeHeap
I am already using, my problems are punctual in some low standard devices, as some Genesis devices, for example. But I want to at least minimize these problems in these devices, which would guarantee me greater reliability in higher devices.– Fernando Leal
Fernando, if you still can’t solve the problem, I can give you one more suggestion. O Brisk, facebook library, can make memory allocation in special area of Android, where it has less size restriction... Isn’t it worth an attempt to allocate that large object there, manipulate and then dislocate? I’ve never used this area, but from what I’ve heard, you’re the one who manages allocation and displacement, so you need to be careful not to forget anything there...
– Wakim
@Wakim, solve not solved, but already improved some situations, the screens that cause problems Outofmemory on the devices mentioned, are the screens of Catalogo, where are screens with grids of images, I am already resizing the images to the appropriate size when loading it to memory, and I am already loading on demand and desalocando on demand, as the user descends and climbs on scroll from the page, but sporadically, it’s not always, Outofmemory happens, so the idea is to optimize everything else to try to keep more memory available for these screens.
– Fernando Leal
@Fernando neither served nor forgot to accept one of them?
– Maniero