关于读取android手机通讯录过程中Excessive JNI global references VM aborting 的问题,日志报错如下:
我在读取通讯录的时候遇到的问题:日志如下,读取800多个人的联系方式的时候就出下面的错误。
08-30 04:48:33.310: DEBUG/dalvikvm(451): GREF has increased to 2001
08-30 04:48:33.310: WARN/dalvikvm(451): Last 10 entries in JNI global reference table:
08-30 04:48:33.320: WARN/dalvikvm(451):  1991: 0x4373ed08 cls=Ljava/lang/ref/WeakReference; (28 bytes)
08-30 04:48:33.320: WARN/dalvikvm(451):  1992: 0x43726990 cls=Ljava/lang/ref/WeakReference; (28 bytes)
08-30 04:48:33.320: WARN/dalvikvm(451):  1993: 0x43740280 cls=Landroid/database/ContentObserver$Transport; (28 bytes)
08-30 04:48:33.320: WARN/dalvikvm(451):  1994: 0x437402a0 cls=Landroid/database/CursorToBulkCursorAdaptor; (44 bytes)
08-30 04:48:33.320: WARN/dalvikvm(451):  1995: 0x437406e0 cls=Ljava/lang/ref/WeakReference; (28 bytes)
08-30 04:48:33.320: WARN/dalvikvm(451):  1996: 0x43740758 cls=Ljava/lang/ref/WeakReference; (28 bytes)
08-30 04:48:33.320: WARN/dalvikvm(451):  1997: 0x43740fb0 cls=Landroid/database/ContentObserver$Transport; (28 bytes)
08-30 04:48:33.320: WARN/dalvikvm(451):  1998: 0x43740fd0 cls=Landroid/database/CursorToBulkCursorAdaptor; (44 bytes)
08-30 04:48:33.320: WARN/dalvikvm(451):  1999: 0x43740fd0 cls=Landroid/database/CursorToBulkCursorAdaptor; (44 bytes)
08-30 04:48:33.320: WARN/dalvikvm(451):  2000: 0x43449678 cls=Ljava/lang/String; (28 bytes)
08-30 04:48:33.349: WARN/dalvikvm(451): JNI global reference table summary (2001 entries):
08-30 04:48:33.359: WARN/dalvikvm(451):    53 of Ljava/lang/Class; 164B (42 unique)
08-30 04:48:33.359: WARN/dalvikvm(451):     2 of Ljava/lang/String; 28B (2 unique)
08-30 04:48:33.359: WARN/dalvikvm(451):    58 of Ljava/lang/ref/WeakReference; 28B (58 unique)
08-30 04:48:33.359: WARN/dalvikvm(451):     2 of Ljava/lang/ref/WeakReference; 36B (2 unique)
08-30 04:48:33.359: WARN/dalvikvm(451):     5 of Landroid/app/ActivityThread$PackageInfo$ReceiverDispatcher$InnerReceiver; 28B (5 unique)
08-30 04:48:33.359: WARN/dalvikvm(451):     1 of Landroid/os/Binder; 20B
08-30 04:48:33.359: WARN/dalvikvm(451):     1 of Ldalvik/system/VMRuntime; 12B
08-30 04:48:33.359: WARN/dalvikvm(451):     1 of Landroid/app/ActivityThread$ProviderRecord; 28B
08-30 04:48:33.359: WARN/dalvikvm(451):     1 of Landroid/app/ActivityThread$ApplicationThread; 28B
08-30 04:48:33.359: WARN/dalvikvm(451):     3 of Landroid/content/ContentProvider$Transport; 28B (3 unique)
08-30 04:48:33.359: WARN/dalvikvm(451):    76 of Landroid/database/ContentObserver$Transport; 28B (76 unique)
08-30 04:48:33.369: WARN/dalvikvm(451):  1744 of Landroid/database/CursorToBulkCursorAdaptor; 44B (1742 unique)
08-30 04:48:33.369: WARN/dalvikvm(451):    52 of Landroid/database/CursorToBulkCursorAdaptor; 52B (52 unique)
08-30 04:48:33.369: WARN/dalvikvm(451):     1 of Landroid/view/ViewRoot$W; 28B
08-30 04:48:33.369: WARN/dalvikvm(451):     1 of Landroid/app/ApplicationContext$WallpaperCallback; 28B
08-30 04:48:33.369: WARN/dalvikvm(451): Memory held directly by native code is 90488 bytes
08-30 04:48:33.369: ERROR/dalvikvm(451): Excessive JNI global references (2001)
08-30 04:48:33.369: ERROR/dalvikvm(451): VM aborting
08-30 04:48:33.473: INFO/DEBUG(20): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
08-30 04:48:33.479: INFO/DEBUG(20): Build fingerprint: 'generic/sdk/generic/:1.1/PLATFORM-1_0/129975:sdk/test-keys'
08-30 04:48:33.479: INFO/DEBUG(20): pid: 451, tid: 537  >>> android.process.acore <<<
08-30 04:48:33.479: INFO/DEBUG(20): signal 11 (SIGSEGV), fault addr deadd00d
08-30 04:48:33.479: INFO/DEBUG(20):  r0 00000320  r1 0000000c  r2 0000000c  r3 00000026
08-30 04:48:33.479: INFO/DEBUG(20):  r4 deadd00d  r5 00000001  r6 000007d1  r7 ad07edf8
08-30 04:48:33.479: INFO/DEBUG(20):  r8 44e6cbc0  r9 42295f2c  10 42295f18  fp 00000001
08-30 04:48:33.479: INFO/DEBUG(20):  ip ad07eed4  sp 44e6cb20  lr afe1238d  pc ad039132  cpsr 20000030
08-30 04:48:33.539: INFO/DEBUG(20):          #00  pc ad039132  /system/lib/libdvm.so
08-30 04:48:33.549: INFO/DEBUG(20):          #01  pc ad03ee22  /system/lib/libdvm.so
08-30 04:48:33.558: INFO/DEBUG(20):          #02  pc ad03ee82  /system/lib/libdvm.so
08-30 04:48:33.580: INFO/DEBUG(20):          #03  pc ad030398  /system/lib/libdvm.so
08-30 04:48:33.590: INFO/DEBUG(20):          #04  pc ad336e0a  /system/lib/libandroid_runtime.so
08-30 04:48:33.590: INFO/DEBUG(20):          #05  pc ad00d9f4  /system/lib/libdvm.so
08-30 04:48:33.599: INFO/DEBUG(20):          #06  pc ad04120e  /system/lib/libdvm.so
08-30 04:48:33.609: INFO/DEBUG(20):          #07  pc ad012748  /system/lib/libdvm.so
08-30 04:48:33.609: INFO/DEBUG(20):          #08  pc ad02a92c  /system/lib/libdvm.so
08-30 04:48:33.619: INFO/DEBUG(20):          #09  pc ad0169d0  /system/lib/libdvm.so
08-30 04:48:33.628: INFO/DEBUG(20):          #10  pc ad051f10  /system/lib/libdvm.so
08-30 04:48:33.628: INFO/DEBUG(20):          #11  pc ad040df2  /system/lib/libdvm.so
08-30 04:48:33.640: INFO/DEBUG(20):          #12  pc ad02e03c  /system/lib/libdvm.so
08-30 04:48:33.640: INFO/DEBUG(20):          #13  pc ad3360fe  /system/lib/libandroid_runtime.so
08-30 04:48:33.650: INFO/DEBUG(20):          #14  pc ad3378a8  /system/lib/libandroid_runtime.so
08-30 04:48:33.660: INFO/DEBUG(20):          #15  pc a9d29f14  /system/lib/libutils.so
08-30 04:48:33.660: INFO/DEBUG(20):          #16  pc a9d2d672  /system/lib/libutils.so
08-30 04:48:33.669: INFO/DEBUG(20):          #17  pc a9d2da44  /system/lib/libutils.so
08-30 04:48:33.679: INFO/DEBUG(20):          #18  pc a9d32236  /system/lib/libutils.so
08-30 04:48:33.679: INFO/DEBUG(20):          #19  pc a9d27898  /system/lib/libutils.so
08-30 04:48:33.689: INFO/DEBUG(20):          #20  pc ad3274b2  /system/lib/libandroid_runtime.so
08-30 04:48:33.699: INFO/DEBUG(20):          #21  pc a9d27674  /system/lib/libutils.so
08-30 04:48:33.709: INFO/DEBUG(20):          #22  pc afe0ed08  /system/lib/libc.so
08-30 04:48:33.709: INFO/DEBUG(20):          #23  pc afe0e87c  /system/lib/libc.so
08-30 04:48:33.719: INFO/DEBUG(20): stack:
08-30 04:48:33.719: INFO/DEBUG(20):     44e6cae0  0000001c  
08-30 04:48:33.730: INFO/DEBUG(20):     44e6cae4  aac08bd3  /system/lib/libsqlite.so
08-30 04:48:33.748: INFO/DEBUG(20):     44e6cae8  afe35f3c  
08-30 04:48:33.748: INFO/DEBUG(20):     44e6caec  afe35f90  
08-30 04:48:33.748: INFO/DEBUG(20):     44e6caf0  00000000  
08-30 04:48:33.748: INFO/DEBUG(20):     44e6caf4  afe1238d  /system/lib/libc.so
08-30 04:48:33.748: INFO/DEBUG(20):     44e6caf8  0083dcf8  [heap]
08-30 04:48:33.748: INFO/DEBUG(20):     44e6cafc  afe11539  /system/lib/libc.so
08-30 04:48:33.748: INFO/DEBUG(20):     44e6cb00  00000000  
08-30 04:48:33.748: INFO/DEBUG(20):     44e6cb04  ad07edf8  
08-30 04:48:33.748: INFO/DEBUG(20):     44e6cb08  00000001  
08-30 04:48:33.748: INFO/DEBUG(20):     44e6cb0c  000007d1  
08-30 04:48:33.748: INFO/DEBUG(20):     44e6cb10  ad07edf8  
08-30 04:48:33.748: INFO/DEBUG(20):     44e6cb14  afe1159d  /system/lib/libc.so
08-30 04:48:33.748: INFO/DEBUG(20):     44e6cb18  df002777  
08-30 04:48:33.748: INFO/DEBUG(20):     44e6cb1c  e3a070ad  
08-30 04:48:33.748: INFO/DEBUG(20): #00 44e6cb20  fffee4d4  
08-30 04:48:33.748: INFO/DEBUG(20):     44e6cb24  ad03ee25  /system/lib/libdvm.so
08-30 04:48:33.748: INFO/DEBUG(20): #01 44e6cb28  ad07edf8  
08-30 04:48:33.748: INFO/DEBUG(20):     44e6cb2c  ad0665f0  /system/lib/libdvm.so
08-30 04:48:33.748: INFO/DEBUG(20):     44e6cb30  ad07fd34  
08-30 04:48:33.748: INFO/DEBUG(20):     44e6cb34  43449678  
08-30 04:48:33.748: INFO/DEBUG(20):     44e6cb38  00000007  
08-30 04:48:33.748: INFO/DEBUG(20):     44e6cb3c  43449678  
08-30 04:48:33.748: INFO/DEBUG(20):     44e6cb40  001c1a08  [heap]
08-30 04:48:33.748: INFO/DEBUG(20):     44e6cb44  00000000  
08-30 04:48:33.748: INFO/DEBUG(20):     44e6cb48  434496a8  
08-30 04:48:33.748: INFO/DEBUG(20):     44e6cb4c  ad03ee85  /system/lib/libdvm.so
08-30 04:48:34.338: DEBUG/dalvikvm(88): GC freed 9293 objects / 524328 bytes in 258ms
08-30 04:48:35.019: INFO/ActivityManager(52): Process android.process.acore (pid 451) has died.
08-30 04:48:35.019: INFO/ActivityManager(52): Killing app com.mycontact (pid 528) because provider com.android.providers.contacts.ContactsProvider is in dying process android.process.acore
08-30 04:48:35.019: INFO/Process(52): Sending signal. PID: 528 SIG: 9
08-30 04:48:35.019: INFO/WindowManager(52): WIN DEATH: Window{434f74d0 com.android.launcher/com.android.launcher.Launcher}
08-30 04:48:35.079: INFO/ActivityManager(52): Process com.mycontact (pid 528) has died.
08-30 04:48:35.099: INFO/WindowManager(52): WIN DEATH: Window{433c1d48 com.mycontact/com.mycontact.Mycontact}
08-30 04:48:35.129: DEBUG/Zygote(23): Process 451 terminated by signal (11)
08-30 04:48:35.209: INFO/ActivityManager(52): Start proc android.process.acore for activity com.android.launcher/.Launcher: pid=549 uid=10005 gids={3003}
08-30 04:48:35.329: INFO/jdwp(549): received file descriptor 10 from ADB
08-30 04:48:35.548: INFO/ActivityThread(549): Publishing provider com.android.googlesearch.SuggestionProvider: com.android.googlesearch.SuggestionProvider
08-30 04:48:35.669: INFO/ActivityThread(549): Publishing provider im: com.android.providers.im.ImProvider
08-30 04:48:35.730: INFO/ActivityThread(549): Publishing provider contacts;call_log: com.android.providers.contacts.ContactsProvider
08-30 04:48:35.950: WARN/GoogleLoginService(122): Device has no accounts: sending Intent { action=android.accounts.LOGIN_ACCOUNTS_MISSING }
08-30 04:48:36.338: DEBUG/dalvikvm(549): GC freed 2432 objects / 149616 bytes in 81ms
08-30 04:48:36.569: DEBUG/dalvikvm(549): GC freed 602 objects / 46600 bytes in 67ms
08-30 04:48:37.139: INFO/ActivityManager(52): Stopping service: com.google.android.googleapps/.GoogleLoginService
08-30 04:48:37.248: INFO/ActivityManager(52): Displayed activity com.android.launcher/.Launcher: 2104 ms
搞了2天,开始以为是自己没有及时释放内存,后来在是Sharyu大哥的帮助下,终于找到问题的所在:

public abstract class

ContentResolver

extends Object
java.lang.Object
   ↳ android.content.ContentResolver
Known Direct Subclasses

Class Overview

This class provides applications access to the content model.

Summary

Constants
String CURSOR_DIR_BASE_TYPE This is the Android platform's base MIME type for a content: URI containing a Cursor of zero or more items.
String CURSOR_ITEM_BASE_TYPE This is the Android platform's base MIME type for a content: URI containing a Cursor of a single item.
String SCHEME_ANDROID_RESOURCE
String SCHEME_CONTENT
String SCHEME_FILE
String SYNC_EXTRAS_ACCOUNT
String SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS
String SYNC_EXTRAS_EXPEDITED
String SYNC_EXTRAS_FORCE
String SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS
String SYNC_EXTRAS_UPLOAD
Public Constructors
ContentResolver(Context context)
Public Methods
final int bulkInsert(Uri url, ContentValues[] values)
Inserts multiple rows into a table at the given URL.
void cancelSync(Uri uri)
final int delete(Uri url, String where, String[] selectionArgs)
Deletes row(s) specified by a content URI.
final String getType(Uri url)
Return the MIME type of the given content URL.
final Uri insert(Uri url, ContentValues values)
Inserts a row into a table at the given URL.
void notifyChange(Uri uri, ContentObserver observer)
Notify registered observers that a row was updated.
void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork)
Notify registered observers that a row was updated.
final AssetFileDescriptor openAssetFileDescriptor(Uri uri, String mode)
Open a raw file descriptor to access data under a "content:" URI.
final ParcelFileDescriptor openFileDescriptor(Uri uri, String mode)
Open a raw file descriptor to access data under a "content:" URI.
final InputStream openInputStream(Uri uri)
Open a stream on to the content associated with a content URI.
final OutputStream openOutputStream(Uri uri)
final OutputStream openOutputStream(Uri uri, String mode)
Open a stream on to the content associated with a content URI.
final Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
Query the given URI, returning a Cursor over the result set.
final void registerContentObserver(Uri uri, boolean notifyForDescendents, ContentObserver observer)
Register an observer class that gets callbacks when data identified by a given content URI changes.
void startSync(Uri uri, Bundle extras)
Start an asynchronous sync operation.
final void unregisterContentObserver(ContentObserver observer)
Unregisters a change observer.
final int update(Uri uri, ContentValues values, String where, String[] selectionArgs)
Update row(s) in a content URI.
static void validateSyncExtrasBundle(Bundle extras)
Check that only values of the following types are in the Bundle:
  • Integer
  • Long
  • Boolean
  • Float
  • Double
  • String
  • null
[Expand]
Inherited Methods
From class java.lang.Object

Constants

public static final String CURSOR_DIR_BASE_TYPE

This is the Android platform's base MIME type for a content: URI containing a Cursor of zero or more items. Applications should use this as the base type along with their own sub-type of their content: URIs that represent a directory of items. For example, hypothetical IMAP email client may have a URI content://com.company.provider.imap/inbox for all of the messages in its inbox, whose MIME type would be reported as CURSOR_DIR_BASE_TYPE + "/vnd.company.imap-msg"

Note how the base MIME type varies between this and CURSOR_ITEM_BASE_TYPE depending on whether there is one single item or multiple items in the data set, while the sub-type remains the same because in either case the data structure contained in the cursor is the same.

Constant Value: "vnd.android.cursor.dir"

public static final String CURSOR_ITEM_BASE_TYPE

This is the Android platform's base MIME type for a content: URI containing a Cursor of a single item. Applications should use this as the base type along with their own sub-type of their content: URIs that represent a particular item. For example, hypothetical IMAP email client may have a URI content://com.company.provider.imap/inbox/1 for a particular message in the inbox, whose MIME type would be reported as CURSOR_ITEM_BASE_TYPE + "/vnd.company.imap-msg"

Compare with CURSOR_DIR_BASE_TYPE.

Constant Value: "vnd.android.cursor.item"

public static final String SCHEME_ANDROID_RESOURCE

 

Constant Value: "android.resource"

public static final String SCHEME_CONTENT

 

Constant Value: "content"

public static final String SCHEME_FILE

 

Constant Value: "file"

public static final String SYNC_EXTRAS_ACCOUNT

 

Constant Value: "account"

public static final String SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS

 

Constant Value: "discard_deletions"

public static final String SYNC_EXTRAS_EXPEDITED

 

Constant Value: "expedited"

public static final String SYNC_EXTRAS_FORCE

 

Constant Value: "force"

public static final String SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS

 

Constant Value: "deletions_override"

public static final String SYNC_EXTRAS_UPLOAD

 

Constant Value: "upload"

Public Constructors

public ContentResolver (Context context)

 

Public Methods

public final int bulkInsert (Uri url, ContentValues[] values)

Inserts multiple rows into a table at the given URL. This function make no guarantees about the atomicity of the insertions.

Parameters
url The URL of the table to insert into.
values The initial values for the newly inserted rows. The key is the column name for the field. Passing null will create an empty row.
Returns
  • the number of newly created rows.

public void cancelSync (Uri uri)

 

public final int delete (Uri url, String where, String[] selectionArgs)

Deletes row(s) specified by a content URI. If the content provider supports transactions, the deletion will be atomic.

Parameters
url The URL of the row to delete.
where A filter to apply to rows before deleting, formatted as an SQL WHERE clause (excluding the WHERE itself).
Returns
  • The number of rows deleted.

public final String getType (Uri url)

Return the MIME type of the given content URL.

Parameters
url A Uri identifying content (either a list or specific type), using the content:// scheme.
Returns
  • A MIME type for the content, or null if the URL is invalid or the type is unknown

public final Uri insert (Uri url, ContentValues values)

Inserts a row into a table at the given URL. If the content provider supports transactions the insertion will be atomic.

Parameters
url The URL of the table to insert into.
values The initial values for the newly inserted row. The key is the column name for the field. Passing an empty ContentValues will create an empty row.
Returns
  • the URL of the newly created row.

public void notifyChange (Uri uri, ContentObserver observer)

Notify registered observers that a row was updated. To register, call registerContentObserver(). By default, CursorAdapter objects will get this notification.

Parameters
observer The observer that originated the change, may be null

public void notifyChange (Uri uri, ContentObserver observer, boolean syncToNetwork)

Notify registered observers that a row was updated. To register, call registerContentObserver(). By default, CursorAdapter objects will get this notification.

Parameters
observer The observer that originated the change, may be null
syncToNetwork If true, attempt to sync the change to the network.

public final AssetFileDescriptor openAssetFileDescriptor (Uri uri, String mode)

Open a raw file descriptor to access data under a "content:" URI. This interacts with the underlying openAssetFile(Uri, String) ContentProvider.openAssetFile()} method of the provider associated with the given URI, to retrieve any file stored there.

Accepts the following URI schemes:
The android.resource (SCHEME_ANDROID_RESOURCE) Scheme

A Uri object can be used to reference a resource in an APK file. The Uri should be one of the following formats:

  • android.resource://package_name/id_number
    package_name is your package name as listed in your AndroidManifest.xml. For example com.example.myapp
    id_number is the int form of the ID.
    The easiest way to construct this form is
    Uri uri = Uri.parse("android.resource://com.example.myapp/" + R.raw.my_resource");
  • android.resource://package_name/type/name
    package_name is your package name as listed in your AndroidManifest.xml. For example com.example.myapp
    type is the string form of the resource type. For example, raw or drawable. name is the string form of the resource name. That is, whatever the file name was in your res directory, without the type extension. The easiest way to construct this form is
    Uri uri = Uri.parse("android.resource://com.example.myapp/raw/my_resource");

 

Parameters
uri The desired URI to open.
mode The file mode to use, as per ContentProvider.openAssetFile.
Returns
  • Returns a new ParcelFileDescriptor pointing to the file. You own this descriptor and are responsible for closing it when done.
Throws
FileNotFoundException Throws FileNotFoundException of no file exists under the URI or the mode is invalid.

public final ParcelFileDescriptor openFileDescriptor (Uri uri, String mode)

Open a raw file descriptor to access data under a "content:" URI. This is like openAssetFileDescriptor(Uri, String), but uses the underlying openFile(Uri, String) ContentProvider.openFile()} method, so will not work with providers that return sub-sections of files. If at all possible, you should use openAssetFileDescriptor(Uri, String). You will receive a FileNotFoundException exception if the provider returns a sub-section of a file.

Accepts the following URI schemes:

See openAssetFileDescriptor(Uri, String) for more information on these schemes.

Parameters
uri The desired URI to open.
mode The file mode to use, as per ContentProvider.openFile.
Returns
  • Returns a new ParcelFileDescriptor pointing to the file. You own this descriptor and are responsible for closing it when done.
Throws
FileNotFoundException Throws FileNotFoundException of no file exists under the URI or the mode is invalid.

public final InputStream openInputStream (Uri uri)

Open a stream on to the content associated with a content URI. If there is no data associated with the URI, FileNotFoundException is thrown.

Accepts the following URI schemes:

See openAssetFileDescriptor(Uri, String) for more information on these schemes.

Parameters
uri The desired URI.
Returns
  • InputStream
Throws
FileNotFoundException if the provided URI could not be opened.

public final OutputStream openOutputStream (Uri uri)

Throws
FileNotFoundException if the provided URI could not be opened.

public final OutputStream openOutputStream (Uri uri, String mode)

Open a stream on to the content associated with a content URI. If there is no data associated with the URI, FileNotFoundException is thrown.

Accepts the following URI schemes:

See openAssetFileDescriptor(Uri, String) for more information on these schemes.

Parameters
uri The desired URI.
mode May be "w", "wa", "rw", or "rwt".
Returns
  • OutputStream
Throws
FileNotFoundException if the provided URI could not be opened.

public final Cursor query (Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)

Query the given URI, returning a Cursor over the result set.

Parameters
uri The URI, using the content:// scheme, for the content to retrieve.
projection A list of which columns to return. Passing null will return all columns, which is discouraged to prevent reading data from storage that isn't going to be used.
selection A filter declaring which rows to return, formatted as an SQL WHERE clause (excluding the WHERE itself). Passing null will return all rows for the given URI.
selectionArgs You may include ?s in selection, which will be replaced by the values from selectionArgs, in the order that they appear in the selection. The values will be bound as Strings.
sortOrder How to order the rows, formatted as an SQL ORDER BY clause (excluding the ORDER BY itself). Passing null will use the default sort order, which may be unordered.
Returns
  • A Cursor object, which is positioned before the first entry, or null