Android: GC_FOR_MALLOC caused by a lengthy touch event? - android

I've been reading around and looking into touchEvents, mainly because my GC is exploding when there is a lengthy touch/slide event OR many touch events. If I do not touch the phone it simply idles as ~5 objects as you can see from the first few GC_EXPLICIT that I performed from DDMS. I then began to touch the screen and sliding around, and the objects shot up around 13513 objects and actually caused a GC_FOR_MALLOC that takes over 100ms. Here was my simple testing code, and below is the log of the dalvicvm tag. If you have documentation of workarounds or causes, or possibly even just another in-depth discussion of this I would greatly appreciate it! Cheers, and good luck on your own endeavors.
[code]
public class testClass extends Activity implements IOnSceneTouchListener{
int numberOfTouches = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
}
#Override
public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
numberOfTouches++;
return false;
}
}
[logcat]
06-28 15:24:55.317: DEBUG/dalvikvm(2501): GC_EXPLICIT freed 5 objects / 128 bytes in 53ms
06-28 15:24:55.903: DEBUG/dalvikvm(2501): GC_EXPLICIT freed 5 objects / 136 bytes in 59ms
06-28 15:24:56.708: DEBUG/dalvikvm(2501): GC_EXPLICIT freed 5 objects / 128 bytes in 59ms
06-28 15:25:06.614: DEBUG/dalvikvm(2501): GC_EXPLICIT freed 6 objects / 168 bytes in 58ms
06-28 15:25:09.833: DEBUG/dalvikvm(2501): GC_EXPLICIT freed 7 objects / 192 bytes in 65ms
06-28 15:25:14.270: DEBUG/dalvikvm(2501): GC_EXPLICIT freed 8 objects / 232 bytes in 59ms
06-28 15:25:18.294: DEBUG/dalvikvm(2501): GC_EXPLICIT freed 6 objects / 160 bytes in 59ms
06-28 15:25:33.942: DEBUG/dalvikvm(1103): GC_FOR_MALLOC freed 13513 objects / 1403264 bytes in 121ms
06-28 15:26:53.684: DEBUG/dalvikvm(2139): GC_EXPLICIT freed 140 objects / 6960 bytes in 99ms
06-28 15:26:58.731: DEBUG/dalvikvm(1215): GC_EXPLICIT freed 668 objects / 71136 bytes in 117ms
06-28 15:27:31.637: DEBUG/dalvikvm(1103): GC_FOR_MALLOC freed 13962 objects / 1504296 bytes in 122ms
06-28 15:27:44.723: DEBUG/dalvikvm(2501): GC_EXPLICIT freed 63 objects / 2152 bytes in 59ms
06-28 15:27:46.676: DEBUG/dalvikvm(2501): GC_EXPLICIT freed 5 objects / 128 bytes in 65ms
06-28 15:27:47.238: DEBUG/dalvikvm(2501): GC_EXPLICIT freed 5 objects / 128 bytes in 58ms
I've yet to actually solve the problem but have stumbled across this great article on this exact problem: Android Touch Problems
[edit]
as stracka said, it's most likely due to flooding. My real issue is however with the allocations that are being made on each event? Is there a way to reuse these events/objects to limit allocations due to touch?
I'm currently using andEngine, and the touchEvents are pooled so there should be at most ~5 ever allocated from scratch; otherwise they just reuse don't they?
Thanks for any ideas....

Are you using an older version of Android? I was just reading about the "touch event flood" problem on Android 1.5 in Beginning Android Games. The author's workaround was to put the UI thread to sleep briefly in his onTouch() handler, to limit the number of events received. I don't know how viable that solution is, or if would be of any use to you; the pertinent page from the book can be found here:
Beginning Android Games, page 131

#Override
public boolean onTouchEvent(MotionEvent event) {
numberOfTouches++;
//events can be handled as well.
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
invalidate();
break;
case MotionEvent.ACTION_MOVE:
invalidate();
break;
case MotionEvent.ACTION_UP:
invalidate();
break;
}
return true;
}
This goes light on GC and mallocs. This is the override method of a View.
Try it and reply..
android.view.View.onTouchEvent(MotionEvent event)
Reference:
http://developer.android.com/reference/android/view/View.html#onTouchEvent%28android.view.MotionEvent%29

Related

Xamarin implementation of ByteBuffer.Get wrong?

Here's a sample function that fills a small ByteBuffer, and then that reads it into a large byte array:
// Allocate the two buffers once for all.
const int byteBufferSize = 20;
var byteBuffer = ByteBuffer.Allocate(byteBufferSize);
/* var byteBufferArray = new byte[byteBufferSize];
var byteBuffer = ByteBuffer.Wrap(byteBufferArray);*/
var bytes = new byte[1024 * 1024];
var bytesPos = 0;
for (;;)
{
// Put byteBuffer in "write" mode.
byteBuffer.Clear();
// Write a few bytes in byteBuffer.
for (var i = 0; i < byteBufferSize; ++i)
byteBuffer.Put(0);
// Put byteBuffer in "read" mode.
byteBuffer.Flip();
// Read the written bytes from byteBuffer.
// DEEP BELOW, THIS CALL UNEXPECTEDLY CAUSES A NASTY ALLOCATION OF ABOUT bytes.length BYTES!
byteBuffer.Get(bytes, bytesPos, byteBufferSize);
bytesPos += byteBufferSize;
Thread.Sleep(1000);
}
When I run this code on Nexus 5 running Android 5.0, it seems to be fine. But when I run it on a Samsung Galaxy S3 running Android 4.3, every time ByteBuffer.Get gets called, it seems a buffer of size bytes.length (1 Mo here) gets allocated somewhere inside ByteBuffer.Get, and after a short while the logs look like:
05-15 09:50:28.519: D/dalvikvm(23104): GC_FOR_ALLOC freed 1024K, 48% free 10250K/19624K, paused 49ms, total 49ms
05-15 09:50:29.580: D/dalvikvm(23104): GC_FOR_ALLOC freed 1024K, 48% free 10250K/19624K, paused 48ms, total 48ms
05-15 09:50:30.622: D/dalvikvm(23104): GC_FOR_ALLOC freed 1024K, 48% free 10250K/19624K, paused 39ms, total 39ms
05-15 09:50:31.673: D/dalvikvm(23104): GC_FOR_ALLOC freed 1024K, 48% free 10250K/19624K, paused 45ms, total 45ms
05-15 09:50:32.724: D/dalvikvm(23104): GC_FOR_ALLOC freed 1024K, 48% free 10250K/19624K, paused 42ms, total 42ms
...
Is it something that I do with the ByteBuffer object or it there something wrong with ByteBuffer.Get in Xamarin? Note that I did test the same code in a native Android Java app the code ran as expected, i.e. without the crazy allocations triggered by ByteBuffer.Get.
In case anyone comes across this page first while researching this issue, I have now filed an enhancement request that discusses the underlying causes of this problem as well some possible workarounds:
https://bugzilla.xamarin.com/show_bug.cgi?id=31260

other packages also run on my android app

I have to run my android application which means am getting the following messages on my logcat window:
12:05:36.056: System_process I/ActivityManager(59): Displayed activity com.xmlparsing/.MainActivity: 581 ms (total 581 ms)
12:05:41.136: com.android.defcon D/dalvikvm(253): GC_EXPLICIT freed 152 objects / 11024 bytes in 60ms
12:05:46.126: com.svox.pico D/dalvikvm(264): GC_EXPLICIT freed 31 objects / 1512 bytes in 50ms
12:05:51.156: com.android.setting D/dalvikvm(125): GC_EXPLICIT freed 975 objects / 42392 bytes in 78ms
12:06:40.666: com.xmlparsing D/dalvikvm(1131): GC_FOR_MALLOC freed 3884 objects / 321368 bytes in 50ms
12:06:40.836: com.xmlparsing D/dalvikvm(1131): GC_FOR_MALLOC freed 3654 objects / 427296 bytes in 48ms
12:06:41.026: com.xmlparsing D/dalvikvm(1131): GC_FOR_MALLOC freed 4007 objects / 418288 bytes in 45ms
12:06:41.245: com.xmlparsing D/dalvikvm(1131): GC_FOR_MALLOC freed 4516 objects / 414608 bytes in 54ms
12:06:41.456: com.xmlparsing D/dalvikvm(1131): GC_FOR_MALLOC freed 4194 objects / 399504 bytes in 53ms
12:06:41.616: com.xmlparsing D/dalvikvm(1131): GC_FOR_MALLOC freed 3365 objects / 412104 bytes in 43ms
12:06:41.666: com.xmlparsing I/System.out(1131): category size6
12:06:41.666: com.xmlparsing I/System.out(1131): category name is---------------->Photos
Here my application package is com.xmlparsing.
But here other packages(com.android.defcon,com.svox.pico,com.android.settings) is running on starting.this packages only taking more time to reading(loading) the data.please check the time.my xml file is read within second.why that package is loading.how can i control it.please give me solution for these
Those packages are not running "on your app". Android supports multitasking, so it is possible to have more than one app alive at a time.
In any case, the LogCat you posted shows that it is simply a GC call, which means Android is trying to free up memory. There is nothing you can do to control this.
If you want to view LogCay messages from only your app, try filtering by process id.
What you're seeing are log messages from the different processes that are going through Garbage Collection (GC).
On any system, Android or otherwise, there will likely be multiple processes running at the same time. On Android, the processes will periodically go through Garbage Collection to free up memory and keep the system running well and within its constrained resources. This is expected behavior.

android service not working when app enters background in titanium

Hi I try to develop a simple Android service application using Titanium by following their tutorial. It works well when the application is in foreground, but when I press back button it kills the app and my service is not running.
Below is the code I used and the log I got when the app enters background. Please let me know where I am going wrong. (I am using Titanium SDK 2.0.1.GA2 and Android SDK 2.2 with Android Runtime v8/Rhino].
My app.js file:
var intent = Titanium.Android.createServiceIntent( { url: 'logservice.js' } );
// Service should run its code every 10 seconds.
intent.putExtra('interval', 10000);
// A message that the service should 'echo'
intent.putExtra('message_to_echo', 'Titanium rocks!');
var service = Titanium.Android.createService(intent);
service.addEventListener('resume', function(e) {
Titanium.API.info('Service code resumes, iteration ' + e.iteration);
});
service.addEventListener('pause', function(e) {
Titanium.API.info('Service code pauses, iteration ' + e.iteration);
/* if (e.iteration === 3) {
Titanium.API.info('Service code has run 3 times, will now stop it.');
service.stop();
} */
});
service.start();
And my logservice.js file is:
var service = Titanium.Android.currentService;
var intent = service.intent;
var message = intent.getStringExtra("message_to_echo");
Titanium.API.info("Hello World! I am a Service. I have this to say: " + message);
I included that service tag in tiapp.xml
And this is the log I am getting when I press back button:
W/KeyCharacterMap( 322): No keyboard for id 0
W/KeyCharacterMap( 322): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
E/TiBaseActivity( 322): (main) [62040,92891] Layout cleanup.
D/dalvikvm( 322): GC_FOR_MALLOC freed 9526 objects / 480272 bytes in 115ms
D/dalvikvm( 322): GC_FOR_MALLOC freed 12770 objects / 693152 bytes in 80ms
D/dalvikvm( 322): GC_FOR_MALLOC freed 8846 objects / 508872 bytes in 77ms
D/dalvikvm( 322): GC_FOR_MALLOC freed 8976 objects / 512112 bytes in 78ms
D/EventEmitter( 322): callHandler function not available for resume
W/TiAnalyticsSvc( 322): (Thread-15) [29966,122857] Analytics Service Started
I/TiAnalyticsSvc( 322): (Thread-15) [69,122926] Sending 1 analytics events.
D/dalvikvm( 322): GC_FOR_MALLOC freed 7386 objects / 436936 bytes in 87ms
D/NativeCrypto( 322): Freeing OpenSSL session
D/dalvikvm( 322): GC_FOR_MALLOC freed 1581 objects / 89648 bytes in 71ms
I/dalvikvm-heap( 322): Grow heap (frag case) to 3.588MB for 87396-byte allocation
D/dalvikvm( 322): GC_FOR_MALLOC freed 12 objects / 712 bytes in 76ms
D/dalvikvm( 322): GC_FOR_MALLOC freed 956 objects / 49400 bytes in 88ms
I/dalvikvm-heap( 322): Grow heap (frag case) to 3.624MB for 87396-byte allocation
D/dalvikvm( 322): GC_FOR_MALLOC freed 0 objects / 0 bytes in 75ms
W/TiAnalyticsSvc( 322): (Thread-15) [3772,126698] Stopping Analytics Service
D/SntpClient( 60): request time failed: java.net.SocketException: Address family not supported by protocol

How to decrease starting time b/w two drawable animations?

I have prepared no.of drawable animations for my application.All are working fine.When application launch drawable animation will be start and i have two buttons(next and previous) in same activity.When i click on next or previous button animation will be change.It is working fine.But when i click on next or previous button it is taking time to changing animations.This my code,
mImgLetter.clearAnimation();
Log.d("before clear","------");
mImgLetter.setBackgroundResource(resID);
Log.d("after clear","------");
mImgLetter.post(new Runnable() {
public void run() {
loadingAnimation = (AnimationDrawable) mImgLetter
.getBackground();
loadingAnimation.start();
}
});
How to decrease starting time b/w two drawable animations when i click on buttons.Please help me.
Logcat is,
02-21 17:52:57.278: D/before clear(813): ------
02-21 17:52:57.337: D/dalvikvm(813): GC freed 285 objects / 12160 bytes in 47ms
02-21 17:52:57.568: D/dalvikvm(813): GC freed 255 objects / 13568 bytes in 50ms
02-21 17:52:57.798: D/dalvikvm(813): GC freed 24 objects / 1016 bytes in 49ms
02-21 17:52:58.018: D/dalvikvm(813): GC freed 24 objects / 1016 bytes in 48ms
02-21 17:52:58.808: D/dalvikvm(813): GC freed 24 objects / 1024 bytes in 52ms
02-21 17:52:59.447: D/dalvikvm(813): GC freed 24 objects / 1016 bytes in 327ms
02-21 17:53:00.127: D/dalvikvm(813): GC freed 26 objects / 1160 bytes in 51ms
02-21 17:53:00.358: D/dalvikvm(813): GC freed 24 objects / 1032 bytes in 49ms
02-21 17:53:01.138: D/dalvikvm(813): GC freed 26 objects / 1552 bytes in 48ms
02-21 17:53:01.678: D/after clear(813): ------
GC will taking lot of time.Let me know how to reduce GC time.

How to find the origin of a GC_FOR_MALLOC?

I'm working on an android app which fall into an infinite loop of GC_FOR_MALLOC freed :
06-15 11:24:56.685: DEBUG/dalvikvm(118): GC_FOR_MALLOC freed 4136 objects / 374744 bytes in 66ms
06-15 11:24:59.176: DEBUG/dalvikvm(521): GC_FOR_MALLOC freed 9340 objects / 524152 bytes in 645ms
06-15 11:24:59.846: DEBUG/dalvikvm(521): GC_FOR_MALLOC freed 9344 objects / 524328 bytes in 149ms
06-15 11:25:01.535: DEBUG/dalvikvm(521): GC_FOR_MALLOC freed 9346 objects / 524448 bytes in 193ms
06-15 11:25:02.175: DEBUG/dalvikvm(521): GC_FOR_MALLOC freed 9344 objects / 524344 bytes in 126ms
The application read some jpeg image over a socket (dedicated thread) and display it in a imageView. The GC loop is bloking the image display.
Is there a solution to know what line or at least what part of the code is throwing the Garbage collection ?
Thanks
I'm not sure if you can access the VM and check why it is performing gc all the time, but gc is usually performed when there is a need for it. You should check what is using so much memory. It may be loading your image (is it a big image?) or perhaps it is something else in your app. Check this post on how to analyse your memory usage and while you are at it check for memory leaks.

Categories

Resources