Bug 22991 - System.DateTime implementation should not use native objects
Summary: System.DateTime implementation should not use native objects
Status: RESOLVED FIXED
Alias: None
Product: Android
Classification: Xamarin
Component: BCL Class Libraries ()
Version: 4.18.0
Hardware: PC Windows
: Normal normal
Target Milestone: ---
Assignee: Jonathan Pryor
URL:
Depends on:
Blocks:
 
Reported: 2014-09-15 07:46 UTC by Holger Benl
Modified: 2014-12-01 17:11 UTC (History)
3 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FIXED

Description Holger Benl 2014-09-15 07:46:55 UTC
In my app I am accessing a webservice using System.Web.Services.Protocols.SoapHttpClientProtocol.
When I use encryption (i.e. an https:// URL), this is what I get in the debug output in Visual Studio
when running the app in the emulator:

*** Calling SoapHttpClientProtocol.Invoke() ***
09-15 06:22:06.679 I/mono-stdout( 3375): *** Calling SoapHttpClientProtocol.Invoke() ***
Thread started:  #4
Thread started: <Thread Pool> #5
Thread started: <Thread Pool> #6
Thread started: <Thread Pool> #7
09-15 06:22:07.619 D/dalvikvm( 3375): GREF has increased to 601
09-15 06:22:07.659 D/dalvikvm( 3375): GREF has increased to 701
09-15 06:22:07.669 D/dalvikvm( 3375): GREF has increased to 801
09-15 06:22:07.669 D/dalvikvm( 3375): GREF has increased to 901
09-15 06:22:07.709 D/dalvikvm( 3375): GREF has increased to 1001
09-15 06:22:07.729 D/dalvikvm( 3375): GREF has increased to 1101
09-15 06:22:07.739 D/dalvikvm( 3375): GREF has increased to 1201
09-15 06:22:07.739 D/dalvikvm( 3375): GREF has increased to 1301
09-15 06:22:07.759 D/dalvikvm( 3375): GREF has increased to 1401
09-15 06:22:07.779 D/dalvikvm( 3375): GREF has increased to 1501
09-15 06:22:07.859 D/dalvikvm( 3375): GREF has increased to 1601
*** SoapHttpClientProtocol.Invoke() returned ***
09-15 06:22:09.409 I/mono-stdout( 3375): *** SoapHttpClientProtocol.Invoke() returned ***


When I use an http:// URL, I get this:

*** Calling SoapHttpClientProtocol.Invoke() ***
09-15 06:23:36.520 I/mono-stdout( 3527): *** Calling SoapHttpClientProtocol.Invoke() ***
Thread started:  #4
Thread started: <Thread Pool> #5
Thread started: <Thread Pool> #6
Thread started: <Thread Pool> #7
*** SoapHttpClientProtocol.Invoke() returned ***
09-15 06:23:37.560 I/mono-stdout( 3527): *** SoapHttpClientProtocol.Invoke() returned ***


(The log messages marked *** are from me - I placed them immediately before and after the call
to SoapHttpClientProtocol.Invoke())

This happens only on the first webservice invocation, all subsequent calls don't show any more
GREFs being used.
The GREFs used by the first webservice invocation are apparently never freed. As a result, my app
now crashes very often due to excessive JNI global references when I try to run it in the emulator.

I have tested this with Xamarin 3.3.47, 3.5.57 and 3.5.58 and the problem started in 3.5.57 and is
still present in 3.5.58.
Comment 1 Holger Benl 2014-09-30 04:59:30 UTC
The source of the problem seems to be how System.DateTime is implemented, my https webservice call was just the first thing triggering the problem since the validation of SSL certificates seems to use lots of System.DateTime objects.

It seems that recent versions of Xamarin.Android implement System.DateTime using java.util.GregorianCalendar and libcore.util.ZoneInfo. This means that every System.DateTime instance needs one or even more GREFs. I would have assumed System.DateTime to be a relatively lightweight object - especially since DateTime is a value type!
So far this has only been a problem for me when running my app in the emulator, where it quickly crashes due to "Excessive JNI global references". But since it's not unusual for the app to hold thousands of DateTime instances at a time I'm afraid that eventually this could also become a problem on real hardware.

Here's a typical JNI global reference table dump:

09-30 04:36:03.188 W/dalvikvm( 2206): JNI global reference table (0xb9e5e1f0) dump:
In mgmain JNI_OnLoad
09-30 04:36:03.188 W/dalvikvm( 2206):   Last 10 entries (of 2001):
09-30 04:36:03.188 W/dalvikvm( 2206):      2000: 0xb31e46c8 java.util.GregorianCalendar
09-30 04:36:03.198 W/dalvikvm( 2206):      1999: 0xb31e4680 libcore.util.ZoneInfo
09-30 04:36:03.198 W/dalvikvm( 2206):      1998: 0xb31e4650 libcore.util.ZoneInfo
09-30 04:36:03.198 W/dalvikvm( 2206):      1997: 0xb31e4560 java.util.GregorianCalendar
09-30 04:36:03.198 W/dalvikvm( 2206):      1996: 0xb31e5830 libcore.util.ZoneInfo
09-30 04:36:03.198 W/dalvikvm( 2206):      1995: 0xb31e5800 libcore.util.ZoneInfo
09-30 04:36:03.198 W/dalvikvm( 2206):      1994: 0xb31e56e0 java.util.GregorianCalendar
09-30 04:36:03.198 W/dalvikvm( 2206):      1993: 0xb31e5698 libcore.util.ZoneInfo
09-30 04:36:03.198 W/dalvikvm( 2206):      1992: 0xb31e5668 libcore.util.ZoneInfo
09-30 04:36:03.198 W/dalvikvm( 2206):      1991: 0xb31e5548 java.util.GregorianCalendar
09-30 04:36:03.198 W/dalvikvm( 2206):   Summary:
09-30 04:36:03.198 W/dalvikvm( 2206):       238 of java.lang.Class (185 unique instances)
09-30 04:36:03.198 W/dalvikvm( 2206):         2 of java.lang.String (2 unique instances)
09-30 04:36:03.198 W/dalvikvm( 2206):         4 of java.io.File (4 unique instances)
09-30 04:36:03.198 W/dalvikvm( 2206):        33 of java.lang.ref.WeakReference (33 unique instances)
09-30 04:36:03.198 W/dalvikvm( 2206):         1 of dalvik.system.PathClassLoader
09-30 04:36:03.198 W/dalvikvm( 2206):         1 of android.graphics.Canvas
09-30 04:36:03.198 W/dalvikvm( 2206):        21 of android.graphics.Typeface (21 unique instances)
09-30 04:36:03.198 W/dalvikvm( 2206):         4 of android.view.MotionEvent (4 unique instances)
09-30 04:36:03.198 W/dalvikvm( 2206):         1 of java.util.Locale
09-30 04:36:03.198 W/dalvikvm( 2206):         1 of android.app.ActivityThread$ApplicationThread
09-30 04:36:03.198 W/dalvikvm( 2206):         1 of android.os.Handler
09-30 04:36:03.198 W/dalvikvm( 2206):         8 of android.content.Intent (8 unique instances)
09-30 04:36:03.198 W/dalvikvm( 2206):         3 of android.app.LoadedApk$ReceiverDispatcher$InnerReceiver (3 unique instances)
09-30 04:36:03.198 W/dalvikvm( 2206):         1 of android.app.NotificationManager
09-30 04:36:03.198 W/dalvikvm( 2206):         1 of android.app.SharedPreferencesImpl
09-30 04:36:03.198 W/dalvikvm( 2206):         2 of android.content.ContentProvider$Transport (2 unique instances)
09-30 04:36:03.198 W/dalvikvm( 2206):         1 of android.database.ContentObserver$Transport
09-30 04:36:03.198 W/dalvikvm( 2206):         1 of android.util.DisplayMetrics
09-30 04:36:03.198 W/dalvikvm( 2206):         1 of android.content.res.Resources
09-30 04:36:03.198 W/dalvikvm( 2206):       477 of java.util.GregorianCalendar (477 unique instances)
09-30 04:36:03.198 W/dalvikvm( 2206):        38 of android.widget.TextView (38 unique instances)
09-30 04:36:03.198 W/dalvikvm( 2206):         1 of android.location.LocationManager
09-30 04:36:03.198 W/dalvikvm( 2206):         1 of android.hardware.display.DisplayManagerGlobal$DisplayManagerCallback
09-30 04:36:03.198 W/dalvikvm( 2206):         1 of android.hardware.input.InputManager$InputDevicesChangedListener
09-30 04:36:03.198 W/dalvikvm( 2206):         2 of android.widget.EditText (2 unique instances)
09-30 04:36:03.198 W/dalvikvm( 2206):         1 of android.net.ConnectivityManager
09-30 04:36:03.198 W/dalvikvm( 2206):         1 of android.os.Looper
09-30 04:36:03.198 W/dalvikvm( 2206):         2 of android.net.Uri$HierarchicalUri (2 unique instances)
09-30 04:36:03.198 W/dalvikvm( 2206):         5 of android.os.Bundle (5 unique instances)
09-30 04:36:03.198 W/dalvikvm( 2206):         1 of android.os.PowerManager
09-30 04:36:03.198 W/dalvikvm( 2206):         1 of android.opengl.EGLSurface
09-30 04:36:03.198 W/dalvikvm( 2206):         1 of android.opengl.EGLContext
09-30 04:36:03.198 W/dalvikvm( 2206):         1 of android.opengl.EGLDisplay
09-30 04:36:03.208 W/dalvikvm( 2206):         1 of android.text.SpannableStringBuilder
09-30 04:36:03.208 W/dalvikvm( 2206):         1 of android.view.Choreographer$FrameDisplayEventReceiver
09-30 04:36:03.208 W/dalvikvm( 2206):         3 of android.view.Display (3 unique instances)
09-30 04:36:03.208 W/dalvikvm( 2206):         2 of android.view.GestureDetector (2 unique instances)
09-30 04:36:03.208 W/dalvikvm( 2206):         1 of android.view.inputmethod.InputMethodManager$1
09-30 04:36:03.208 W/dalvikvm( 2206):         8 of android.view.MenuInflater (8 unique instances)
09-30 04:36:03.208 W/dalvikvm( 2206):         4 of android.view.Surface$CompatibleCanvas (4 unique instances)
09-30 04:36:03.208 W/dalvikvm( 2206):        15 of android.view.inputmethod.InputMethodManager$ControlledInputConnectionWrapper (15 unique instances)
09-30 04:36:03.208 W/dalvikvm( 2206):        14 of android.view.ViewRootImpl$W (14 unique instances)
09-30 04:36:03.208 W/dalvikvm( 2206):         3 of android.view.WindowManagerImpl (3 unique instances)
09-30 04:36:03.208 W/dalvikvm( 2206):         1 of android.view.accessibility.AccessibilityManager$1
09-30 04:36:03.208 W/dalvikvm( 2206):         2 of android.webkit.WebView (2 unique instances)
09-30 04:36:03.208 W/dalvikvm( 2206):         2 of android.webkit.WebSettingsClassic (2 unique instances)
09-30 04:36:03.208 W/dalvikvm( 2206):         4 of android.widget.Button (4 unique instances)
09-30 04:36:03.208 W/dalvikvm( 2206):        10 of android.widget.ImageButton (10 unique instances)
09-30 04:36:03.208 W/dalvikvm( 2206):         6 of android.widget.ImageView (6 unique instances)
09-30 04:36:03.208 W/dalvikvm( 2206):        20 of android.widget.LinearLayout (20 unique instances)
09-30 04:36:03.208 W/dalvikvm( 2206):         6 of android.widget.LinearLayout$LayoutParams (6 unique instances)
09-30 04:36:03.208 W/dalvikvm( 2206):         1 of android.widget.Toast$TN
09-30 04:36:03.208 W/dalvikvm( 2206):         8 of com.android.internal.view.menu.MenuBuilder (8 unique instances)
09-30 04:36:03.208 W/dalvikvm( 2206):         6 of com.android.internal.policy.impl.PhoneLayoutInflater (6 unique instances)
09-30 04:36:03.208 W/dalvikvm( 2206):         8 of com.android.internal.app.ActionBarImpl (8 unique instances)
09-30 04:36:03.208 W/dalvikvm( 2206):         6 of com.android.internal.view.menu.MenuItemImpl (6 unique instances)
09-30 04:36:03.208 W/dalvikvm( 2206):         1 of java.net.Proxy
09-30 04:36:03.208 W/dalvikvm( 2206):         1 of java.net.ProxySelectorImpl
09-30 04:36:03.208 W/dalvikvm( 2206):       952 of libcore.util.ZoneInfo (952 unique instances)
09-30 04:36:03.208 W/dalvikvm( 2206):         1 of argossmartmobile.TheApp
09-30 04:36:03.208 W/dalvikvm( 2206):         1 of argossmartmobile.CacheContentProvider
09-30 04:36:03.208 W/dalvikvm( 2206):         4 of argossmartmobile.McPathView (4 unique instances)
09-30 04:36:03.208 W/dalvikvm( 2206):         1 of argossmartmobile.BluetoothDiscoveryHelper
09-30 04:36:03.208 W/dalvikvm( 2206):         1 of argossmartmobile.SignInActivity
09-30 04:36:03.208 W/dalvikvm( 2206):         1 of android.location.Geocoder
09-30 04:36:03.208 W/dalvikvm( 2206):         1 of argossmartmobile.AndroidGeoLocationManager
09-30 04:36:03.208 W/dalvikvm( 2206):         1 of android.location.Criteria
09-30 04:36:03.208 W/dalvikvm( 2206):         2 of argossmartmobile.JobFormWebActivity (2 unique instances)
09-30 04:36:03.208 W/dalvikvm( 2206):         4 of mono.android.widget.AdapterView_OnItemClickListenerImplementor (4 unique instances)
09-30 04:36:03.208 W/dalvikvm( 2206):         2 of argossmartmobile.PersistentJobFormWebActivityState (2 unique instances)
09-30 04:36:03.208 W/dalvikvm( 2206):         4 of argossmartmobile.McViewListAdapter (4 unique instances)
09-30 04:36:03.208 W/dalvikvm( 2206):         6 of argossmartmobile.JobStateView (6 unique instances)
09-30 04:36:03.208 W/dalvikvm( 2206):         2 of argossmartmobile.JobFormWebActivity_JobFormGestureListener (2 unique instances)
09-30 04:36:03.208 W/dalvikvm( 2206):         1 of dashboardimpl.DashboardLayout
09-30 04:36:03.208 W/dalvikvm( 2206):         1 of mono.android.view.View_OnKeyListenerImplementor
09-30 04:36:03.208 W/dalvikvm( 2206):         1 of argossmartmobile.DashboardActivity
09-30 04:36:03.208 W/dalvikvm( 2206):         4 of argossmartmobile.McViewListView (4 unique instances)
09-30 04:36:03.208 W/dalvikvm( 2206):         4 of argossmartmobile.McViewListActivity (4 unique instances)
09-30 04:36:03.208 W/dalvikvm( 2206):         2 of argossmartmobile.JobFormWebViewClient (2 unique instances)
09-30 04:36:03.208 W/dalvikvm( 2206):        10 of mono.android.view.View_OnClickListenerImplementor (10 unique instances)
09-30 04:36:03.208 W/dalvikvm( 2206):         2 of argossmartmobile.JobFormWebView (2 unique instances)
Comment 2 Jonathan Pryor 2014-09-30 22:45:12 UTC
The use of Java types isn't for DateTime calculations, per-se. They're used for TimeZone calculations. If your DateTime code doesn't use timezones, it shouldn't come into play...

That said, monodroid/836497dd ensures that generated temporary Java instances are disposed.
Comment 3 Mohit Kheterpal 2014-12-01 07:51:04 UTC
Today I am trying to verify this issue but I am not sure about the steps. 

If possible, could you please provide some steps/sample? So that I can verify this issue at my end.

Thanks
Comment 4 Jonathan Pryor 2014-12-01 17:11:47 UTC
@Mohit:

1. Enable GREF logging.
2. Call DateTime.Now in a loop
3. Observe GREF count while running the app. The GREF count shouldn't change while the loop executes.