我有一个Android项目,并且需要在屏幕上显示当前时间的活动。所以我使用了一个工作线程,每秒一次将消息发布到主线程处理程序中。在处理程序中,我格式化当前时间并在UI上显示它。但是每运行30分钟后我得到一个参考表溢出问题,我的程序因错误而崩溃了。这是日志:
ReferenceTable overflow (max=1024)
JNI pinned array reference table (0x6080b458) dump:
Last 10 entries (of 1024):
1023: 0x423b76d0 int[] (1 elements)
1022: 0x4209cea0 int[] (1 elements)
1021: 0x4209c890 int[] (1 elements)
1020: 0x42242198 int[] (1 elements)
1019: 0x421b7b60 int[] (1 elements)
1018: 0x420c0e08 int[] (1 elements)
1017: 0x42107c18 int[] (1 elements)
1016: 0x421078e8 byte[] (1 elements)
1015: 0x42116a18 int[] (1 elements)
1014: 0x42116408 int[] (1 elements)
Summary:
1 of byte[] (1 elements)
1023 of int[] (1 elements) (1023 unique instances)
Failed adding to JNI pinned array ref table (1024 entries)
"main" prio=5 tid=1 RUNNABLE
| group="main" sCount=0 dsCount=0 obj=0x417f5de0 self=0x417e44a8
| sysTid=7820 nice=0 sched=0/0 cgrp=apps handle=1074331988
| state=R schedstat=( 0 0 0 ) utm=972 stm=228 core=0
at libcore.icu.NativeDecimalFormat.formatLong(Native Method)
at libcore.icu.NativeDecimalFormat.formatLong(NativeDecimalFormat.java:253)
at java.text.DecimalFormat.format(DecimalFormat.java:684)
at java.text.NumberFormat.format(NumberFormat.java:299)
at java.text.DecimalFormat.format(DecimalFormat.java:702)
at java.text.SimpleDateFormat.appendNumber(SimpleDateFormat.java:785)
at java.text.SimpleDateFormat.append(SimpleDateFormat.java:676)
at java.text.SimpleDateFormat.formatImpl(SimpleDateFormat.java:553)
at java.text.SimpleDateFormat.format(SimpleDateFormat.java:818)
at java.text.DateFormat.format(DateFormat.java:307)
at com.tuyou.tsd.launcher.SleepingActivity.updateTime(SleepingActivity.java:206)
at com.tuyou.tsd.launcher.SleepingActivity.access$1(SleepingActivity.java:204)
at com.tuyou.tsd.launcher.SleepingActivity$2.handleMessage(SleepingActivity.java:66)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5146)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:732)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:566)
at dalvik.system.NativeStart.main(Native Method)
VM aborting
Fatal signal 6 (SIGABRT) at 0x00001e8c (code=-6), thread 7820 (com.tuyou.tsd)
我注意到在SimpleDateFormat.format()方法调用中发生了崩溃。通过查看源代码,我发现该方法只是通过
实现return format(date, new StringBuffer(), new FieldPosition(0)).toString();
所以我想知道StringBuffer和FieldPosition是否可能导致内存泄漏?或者我的程序运行得太快,以至于对象很快就会变得干净,因此在ref表中引起了太多的对象?这是我的工具代码:
public class SleepingActivity extends BaseActivity {
…
private TimeTask mTimeTask = null;
private SimpleDateFormat mDateFormat = new SimpleDateFormat("HH:mm", Locale.CHINA);
private Date mCurrentTime = new Date();
…
private Handler mHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 100:
updateTime();
break;
default:
super.handleMessage(msg);
}
}
};
private void updateTime() {
mCurrentTime.setTime(System.currentTimeMillis());
String time = mDateFormat.format(mCurrentTime); // problem happened here!
if (mTimeView != null) {
mTimeView.setText(time);
}
}
private class TimeTask extends Thread {
private boolean stop;
@Override
public void run() {
Looper.getMainLooper();
while (!stop) {
Message msg = Message.obtain(null, 100);
mHandler.sendMessage(msg);
try { Thread.sleep(1000); } catch (InterruptedException e) {}
}
}
}
…
}
请帮忙...... Thx。
=============================================== ============ 编辑: 只需尝试找出根本原因,通过注释掉updateTime()中的所有行,运行大约30分钟后。我得到了另一个参考表溢出错误,这似乎与以前不同。
ReferenceTable overflow (max=1024)
JNI pinned array reference table (0x60865460) dump:
Last 10 entries (of 1024):
1023: 0x42269d20 int[] (1 elements)
1022: 0x42269478 int[] (1 elements)
1021: 0x42262e50 int[] (1 elements)
1020: 0x42262dc0 int[] (1 elements)
1019: 0x42262d28 byte[] (1 elements)
1018: 0x4225d800 int[] (1 elements)
1017: 0x42258af0 int[] (1 elements)
1016: 0x42256940 int[] (1 elements)
1015: 0x422535d0 int[] (1 elements)
1014: 0x42251390 int[] (1 elements)
Summary:
1 of byte[] (1 elements)
1023 of int[] (1 elements) (1023 unique instances)
Failed adding to JNI pinned array ref table (1024 entries)
"Binder_3" prio=5 tid=24 RUNNABLE
| group="main" sCount=0 dsCount=0 obj=0x42151ee0 self=0x60ae8008
| sysTid=5507 nice=0 sched=0/0 cgrp=apps handle=1627171640
| state=R schedstat=( 0 0 0 ) utm=2 stm=1 core=0
at android.os.Parcel.nativeEnforceInterface(Native Method)
at android.os.Parcel.enforceInterface(Parcel.java:451)
at android.app.ApplicationThreadNative.onTransact(ApplicationThreadNative.java:383)
at android.os.Binder.execTransact(Binder.java:404)
at dalvik.system.NativeStart.run(Native Method)
VM aborting
答案 0 :(得分:0)
我找到了这个问题的根本原因。它与Java方法无关,它是我的JNI函数调用之一,使用
(*env)->ReleaseByteArrayElements(env, buf, buf_char, JNI_ABORT);
分配一个数组,但在使用后没有释放它。因此在运行30分钟后,ref表溢出。添加
{{1}}问题永远不会再发生了。