Find a leak in Android - java

I'm trying to find a leak in my app that make the device warms without intensive usage. Is there a way of seeing the number of times a method is called and the CPU time expent for it.
I'm asking that because I don't remember its name now, but for C there is a tool that after compile the app with some special parameters, gives that info

Have a look at Profiling with Traceview and dmtracedump. Link

Related

Taking nearly 400 MB of memory at android app startup

First of all, I have seen other questions which might be a duplicate of mine. But none of them could provide me with solution.
There is too much memory consumption at the app startup compared to when it is reached in MainActivity.
At Application class , there is only analytic and facebook sdk initialization. Splash activity contains only logic to check whether user has login before or not. Any Idea what is behind this ? Thanks for paying attention.
You can use Android Studio's memory profiler to see what objects are being allocated and what causes these allocations. It can show you stacktrase of every object allocation. See the docs please.

DDMS reporting incorrect memory usage?

I'm currently investigating one of our Android applications for memory leaks and I found something that completely baffles me.
The DDMS heap monitor reports that the application is using 13mb/20mb heap memory, but a report pulled directly from the device is reporting that the application is using nearly 700mb!
Is this an issue with the device? Is DDMS wrong? How do I find out what is going into that 700mb?
It is part of the system software
The first screenshot is the output of adb shell dumpsys meminfo. The second screenshot looks like it is from procrank, which isn't part of standard Android; leastways, I can't find it quickly on Android 6.0.
(in the future, when somebody asks you 'what exactly is this "report"', feel free to cite actual commands)
Is this an issue with the device?
Probably not, though that's tough to say, since we do not know what the device is, what the app is, or much of anything outside of two digital camera photos.
Is DDMS wrong?
Probably not. Java code, whether running in Dalvik or ART, has a heap limit, and that's going to be well under 700MB.
How do I find out what is going into that 700mb?
~600MB of that will be coming from native code (NDK libraries), most likely.
So, start by finding out what in your app is using native code. That could be your code, or it could come from third-party libraries (e.g., Fresco). Your choices then are:
Call (or implement) logic in those libraries to cap how much heap space they use, or
Get rid of them, or
See if there's a way of hooking up Valgrind or something else to NDK code to determine where and how those libraries are using so much system RAM

jvisualvm doesn't exclude certain methods from CPU profiling

I am trying to profile an application with jvisualvm. The application consists of a loop, in which data is loaded from a database and then some complex calculations are performed on the data. When a set of data is processed, the next set is loaded and calculated.
When I start my application and attach jvisualvm, I set up a filter on the CPU profiling page ("Sart profiling from classes" and "Do not profile classes"), since I am not interested in anything that relates to the database access, and other input/output related stuff.
The filter works - almost. My problem is, that the profiler reports most of the time is spent in sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(), even though sun.* is entered into the "Do not profile classes" filter. This is the only method in sun.* appearing in my profiling results.
Has anyone seen this before and knows how to get rid of it? Problem is, all other methods show up only with tiny amounts (<1%) in the "Self Time" column, most are displayed with 0%.
The jvisualvm version used is 1.3.2.
Thanks in advance,
Axel
Sounds like most of the time is spent waiting from the database. If you want to profile the rest of the stuff, you can either
stub the database so that it returns quickly (thus making the rest of your code take most of the time), or
use a better profiler such as YourKit or JProfiler (paid, definitely support what you want) or TPTP (free, but I'm not sure how powerful it us)
Uncheck 'Profile new Runnables' on the CPU profiling page.
To answer your other question with "Self Time" - you need to take a CPU snapshot of profiled data. The snapshot contains total method time info.

How to debug Java memory errors?

There is a Java Struts application running on Tomcat, that have some memory errors. Sometimes it becomes slowly and hoard all of the memory of Tomcat, until it crashes.
I know how to find and repair "normal code errors", using tests, debugging, etc, but I don't know how to deal with memory errors (How can I reproduce? How can I test? What are the places of code where is more common create a memory error? ).
In one question: Where can I start? Thanks
EDIT:
A snapshot sended by the IT Department (I haven't direct access to the production application)
Use one of the many "profilers". They hook into the JVM and can tell you things like how many new objects are being created per second, and what type they are etc.
Here's just one of many: http://www.ej-technologies.com/products/jprofiler/overview.html
I've used this one and it's OK.
http://kohlerm.blogspot.com/
It is quite good intro how to find memory leaks using eclipse memory analyzer.
If you prefer video tutorials, try youtube, although it is android specific it is very informative.
If your application becomes slowly you could create a heap dump and compare it to another heap dump create when the system is in a healthy condition. Look for differences in larger data structures.
You should run it under profiler (jprofile or yourkit, for example) for some time and see for memory/resource usage. Also try to make thread dumps.
There are couple of options profiler is one of them, another is to dump java heap to a file and analyze it with a special tool (i.e. IBM jvm provides a very cool tool called Memory Analizer that presents very detailed report of allocated memory in the time of jvm crash - http://www.ibm.com/developerworks/java/jdk/tools/memoryanalyzer/).
3rd option is to start your server with jmx server enabled and connect to it via JConsole with this approach you would be able to monitor memory ussage/allocation in the runtime. JConsole is provided with standard sun jdk under bin directory (here u may find how to connect to tomcat via jconsole - Connecting remote tomcat JMX instance using jConsole)

Trying to cause java.lang.OutOfMemoryException

I am trying to reproduce java.lang.OutOfMemoryException in Jboss4, which one of our client got, presumably by running the J2EE applications over days/weeks.
I am trying to find a way for the webapp to spitout java.lang.OutOfMemoryException in a matter of minutes (instead of days/weeks).
One thing come into mind is to write a selenium script and has the script bombards the webapps.
One other thing that we can do is to reduce JVM heap size, but we would prefer not to do this, as we want to see the limit of our system.
Any suggestions?
ps: I don't have access to the source code, as we just provide a hosting service (of course I could decompile the class files...)
If you don't have access to the source code of the J2EE app in question, the options that come to mind are:
Reduce the amount of RAM available to the JVM. You've already identified this one and said you don't want to do it.
Create a J2EE app (it could probably just be a JSP) and configure it to run within the same JVM as the target app, and have that app allocate a ridiculous amount of memory. That will reduce the amount of memory available to the target app, hopefully such that it fails in the way you're trying to force.
Try to use some profiling tools to investigate memory leakage. Also good to investigate memory damps that was taken after OOM happens and logs. IMHO: reducing memory is not the rightest way to investigate cose you can get issues not connected with real production one.
Do both, but in a controlled fashion :
Reduce the available memory to the absolute minimum (using -Xms1M -Xmx2M, as an example, but I fear your app won't even load with such limitations)
Do controlled "nuclear irradiation" : do Selenium scripts or each of the known working urls before to attack the presumed guilty one.
Finally, unleash the power that shall not be raised : start VisualVM and any other monitoring software you can think of (DB execution is a usual suspect).
If you are using Sun Java 6, you may want to consider attaching to the application with jvisualvm in the JDK. This will allow you to do in-place profiling without needing to alter anything in your scenario, and may possibly immediately reveal the culprit.
If you don't have the source use decompile it, at least if you think the terms of usage allows this and you live in a free country. You can use:
Java Decompiler or JAD.
In addition to all the others I must say that even if you can reproduce an OutOfMemory error, and find out where it occurred, you probably haven't found out anything worth knowing.
The trouble is that an OOM occurs when an allocation can not take place. The real problem however is not that allocation, but the fact that other allocations, in other parts of the code, have not been de-allocated (de-referenced and garbage collected). The failed allocation here might have nothing to do with the source of the trouble (no pun intended).
This problem is larger in your case as it might take weeks before trouble starts, suggesting either a sparsely used application, or an abnormal code path, or a relatively HUGE amount of memory in relation to what would be necessary if the code was OK.
It might be a good idea to ask around why this amount of memory is configured for JBoss and not something different. If it's recommended by the supplier than maybe they already know about the leak and require this to mitigate the effects of the bug.
For these kind of errors it really pays to have some idea in which code path the problem occurs so you can do targeted tests. And test with a profiler so you can see during run-time which objects (Lists, Maps and such) are growing without shrinking.
That would give you a chance to decompile the correct classes and see what's wrong with them. (Closing or cleaning in a try block and not a finally block perhaps).
In any case, good luck. I think I'd prefer to find a needle in a haystack. When you find the needle you at least know you have found it:)
The root of the problem is most likely a memory leak in the webapp that the client is running. In order to track it down, you need to run the app with a representative workload with memory profiling enabled. Take some snapshots, and then use the profiler to compare the snapshots to see where objects are leaking. While source-code would be ideal, you should be able to at least figure out where the leaking objects are being allocated. Then you need to track down the cause.
However, if your customer won't release binaries so that you can run an identical system to what he is running, you are kind of stuck, and you'll need to get the customer to do the profiling and leak detection himself.
BTW - there is not a lot of point causing the webapp to throw an OutOfMemoryError. It won't tell you why it is happening, and without understanding "why" you cannot do much about it.
EDIT
There is not point "measuring the limits", if the root cause of the memory leak is in the client's code. Assuming that you are providing a servlet hosting service, the best thing to do is to provide the client with instructions on how to debug memory leaks ... and step out of the way. And if they have a support contract that requires you to (in effect) debug their code, they ought to provide you with the source code to do your job.

Categories

Resources