使用 Volley 的后台服务出现 OutofMemory 错误
OutofMemory error on background service using Volley
我正在制作一个始终运行后台服务的应用程序。但问题是,几个小时后,它会抛出以下内存不足错误:
09-04 22:08:09.110 13810-13810/? I/art? Late-enabling -Xcheck:jni
09-04 22:08:09.165 13810-13810/com.mts.myapp I/MyService? FileScannerService Timer started....
09-04 22:08:10.265 13810-13834/com.mts.myapp I/art? Forcing collection of SoftReferences for 1GB allocation
09-04 22:08:10.280 13810-13834/com.mts.myapp E/art? Throwing OutOfMemoryError "Failed to allocate a 1627389964 byte allocation with 2648453 free bytes and 88MB until OOM"
09-04 22:08:10.310 13810-13834/com.mts.myapp I/art? Forcing collection of SoftReferences for 1GB allocation
09-04 22:08:10.350 13810-13834/com.mts.myapp E/art? Throwing OutOfMemoryError "Failed to allocate a 1627389964 byte allocation with 2648538 free bytes and 88MB until OOM"
09-04 22:08:10.355 13810-13834/com.mts.myapp E/AndroidRuntime? FATAL EXCEPTION: Thread-1654
Process: com.mts.myapp, PID: 13810
java.lang.OutOfMemoryError: Failed to allocate a 1627389964 byte allocation with 2648538 free bytes and 88MB until OOM
at com.android.volley.toolbox.DiskBasedCache.streamToBytes(DiskBasedCache.java:316)
at com.android.volley.toolbox.DiskBasedCache.readString(DiskBasedCache.java:526)
at com.android.volley.toolbox.DiskBasedCache.readStringStringMap(DiskBasedCache.java:549)
at com.android.volley.toolbox.DiskBasedCache$CacheHeader.readHeader(DiskBasedCache.java:392)
at com.android.volley.toolbox.DiskBasedCache.initialize(DiskBasedCache.java:155)
at com.android.volley.CacheDispatcher.run(CacheDispatcher.java:84)
09-04 22:08:25.260 13810-13949/com.mts.myapp I/art? Forcing collection of SoftReferences for 1GB allocation
09-04 22:08:25.280 13810-13949/com.mts.myapp E/art? Throwing OutOfMemoryError "Failed to allocate a 1627389964 byte allocation with 2651578 free bytes and 88MB until OOM"
09-04 22:08:25.310 13810-13949/com.mts.myapp I/art? Forcing collection of SoftReferences for 1GB allocation
09-04 22:08:25.330 13810-13949/com.mts.myapp E/art? Throwing OutOfMemoryError "Failed to allocate a 1627389964 byte allocation with 2651568 free bytes and 88MB until OOM"
09-04 22:08:25.330 13810-13949/com.mts.myapp I/Process? Sending signal. PID: 13810 SIG: 9
该服务在定义的时间间隔内使用 volleys 进行 Http 调用。检查返回的 JSONObject 并在必要时显示通知。
那么您认为是什么导致了内存不足错误?
这是截击:
RequestQueue queue = Volley.newRequestQueue(this);
String url = "http://myrequesturl.com"
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
//DO STUFF
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
queue.add(stringRequest);
某处内存泄漏。
这段代码似乎在每次调用时都会创建一个新的 RequestQueue,这不是 volley 的推荐方法。
您应该创建一个 RequestQueue,然后将我们的请求添加到这个队列中。
每次发出 http 请求时,您的服务都会创建新的请求队列,最好的方法是使用请求队列的单例对象并为每个请求重用它。
这是代码示例
//新建Java文件App.java
public class App extends Application {
public static final String TAG = App.class.getSimpleName();
private static App mInstance;
private RequestQueue mRequestQueue;
public static synchronized App getInstance() {
return mInstance;
}
@Override
public void onCreate() {
super.onCreate();
mRequestQueue = Volley.newRequestQueue(getApplicationContext());
mInstance = this;
}
public RequestQueue getRequestQueue() {
return mRequestQueue;
}
public <T> void addToRequestQueue(Request<T> request, String tag) {
request.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
getRequestQueue().add(request);
}
public <T> void addToRequestQueue(Request<T> request) {
request.setTag(TAG);
getRequestQueue().add(request);
}
public void cancelPendingRequest(Object tag) {
getRequestQueue().cancelAll(tag);
}
}
// 在 android 中该应用程序的清单引用名称 class
<application
android:name=".App"
....
//现在只要你提出请求就这样做
App.getInstance().addToRequestQueue(stringRequest);
这将只创建一个请求队列实例并将其用于每个请求
我正在制作一个始终运行后台服务的应用程序。但问题是,几个小时后,它会抛出以下内存不足错误:
09-04 22:08:09.110 13810-13810/? I/art? Late-enabling -Xcheck:jni
09-04 22:08:09.165 13810-13810/com.mts.myapp I/MyService? FileScannerService Timer started....
09-04 22:08:10.265 13810-13834/com.mts.myapp I/art? Forcing collection of SoftReferences for 1GB allocation
09-04 22:08:10.280 13810-13834/com.mts.myapp E/art? Throwing OutOfMemoryError "Failed to allocate a 1627389964 byte allocation with 2648453 free bytes and 88MB until OOM"
09-04 22:08:10.310 13810-13834/com.mts.myapp I/art? Forcing collection of SoftReferences for 1GB allocation
09-04 22:08:10.350 13810-13834/com.mts.myapp E/art? Throwing OutOfMemoryError "Failed to allocate a 1627389964 byte allocation with 2648538 free bytes and 88MB until OOM"
09-04 22:08:10.355 13810-13834/com.mts.myapp E/AndroidRuntime? FATAL EXCEPTION: Thread-1654
Process: com.mts.myapp, PID: 13810
java.lang.OutOfMemoryError: Failed to allocate a 1627389964 byte allocation with 2648538 free bytes and 88MB until OOM
at com.android.volley.toolbox.DiskBasedCache.streamToBytes(DiskBasedCache.java:316)
at com.android.volley.toolbox.DiskBasedCache.readString(DiskBasedCache.java:526)
at com.android.volley.toolbox.DiskBasedCache.readStringStringMap(DiskBasedCache.java:549)
at com.android.volley.toolbox.DiskBasedCache$CacheHeader.readHeader(DiskBasedCache.java:392)
at com.android.volley.toolbox.DiskBasedCache.initialize(DiskBasedCache.java:155)
at com.android.volley.CacheDispatcher.run(CacheDispatcher.java:84)
09-04 22:08:25.260 13810-13949/com.mts.myapp I/art? Forcing collection of SoftReferences for 1GB allocation
09-04 22:08:25.280 13810-13949/com.mts.myapp E/art? Throwing OutOfMemoryError "Failed to allocate a 1627389964 byte allocation with 2651578 free bytes and 88MB until OOM"
09-04 22:08:25.310 13810-13949/com.mts.myapp I/art? Forcing collection of SoftReferences for 1GB allocation
09-04 22:08:25.330 13810-13949/com.mts.myapp E/art? Throwing OutOfMemoryError "Failed to allocate a 1627389964 byte allocation with 2651568 free bytes and 88MB until OOM"
09-04 22:08:25.330 13810-13949/com.mts.myapp I/Process? Sending signal. PID: 13810 SIG: 9
该服务在定义的时间间隔内使用 volleys 进行 Http 调用。检查返回的 JSONObject 并在必要时显示通知。
那么您认为是什么导致了内存不足错误?
这是截击:
RequestQueue queue = Volley.newRequestQueue(this);
String url = "http://myrequesturl.com"
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
//DO STUFF
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
queue.add(stringRequest);
某处内存泄漏。
这段代码似乎在每次调用时都会创建一个新的 RequestQueue,这不是 volley 的推荐方法。
您应该创建一个 RequestQueue,然后将我们的请求添加到这个队列中。
每次发出 http 请求时,您的服务都会创建新的请求队列,最好的方法是使用请求队列的单例对象并为每个请求重用它。
这是代码示例 //新建Java文件App.java
public class App extends Application {
public static final String TAG = App.class.getSimpleName();
private static App mInstance;
private RequestQueue mRequestQueue;
public static synchronized App getInstance() {
return mInstance;
}
@Override
public void onCreate() {
super.onCreate();
mRequestQueue = Volley.newRequestQueue(getApplicationContext());
mInstance = this;
}
public RequestQueue getRequestQueue() {
return mRequestQueue;
}
public <T> void addToRequestQueue(Request<T> request, String tag) {
request.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
getRequestQueue().add(request);
}
public <T> void addToRequestQueue(Request<T> request) {
request.setTag(TAG);
getRequestQueue().add(request);
}
public void cancelPendingRequest(Object tag) {
getRequestQueue().cancelAll(tag);
}
}
// 在 android 中该应用程序的清单引用名称 class
<application
android:name=".App"
....
//现在只要你提出请求就这样做
App.getInstance().addToRequestQueue(stringRequest);
这将只创建一个请求队列实例并将其用于每个请求