数据库对象被 GC 释放而没有先关闭
Database object was released by the GC without being closed first
我这里有一个奇怪的问题,它告诉我一些数据库对象被释放了,尽管在下面显示的方法中至少没有数据库连接。
控制台输出:
SOMETIMES I DROP GC stuff
WITH FILENAME stuff
WITH FILENAME stuff
WITH FILENAME stuff
**** WARNING! Database object was released by the GC without being closed first! This might cause crashes on iOS *****
**** WARNING! Database object was released by the GC without being closed first! This might cause crashes on iOS *****
**** WARNING! Database object was released by the GC without being closed first! This might cause crashes on iOS *****
WITH FILENAME stuff
WITH FILENAME stuff
WITH FILENAME stuff
AND GC stuff is somewhere here
以及对应的方法
@Override
protected boolean initListModelPhotoList(List cmp) {
Integer imgHeight = Display.getInstance().getDisplayHeight() / 10;
Image placeholderImg = fetchResourceFile().getImage("camera_placeholder.png");
System.err.println("SOMETIMES I DROP GC stuff");
Storage storage = Storage.getInstance();
Vector vector = new Vector();
for (xyz.model.Image image : images) {
if (!image.getDeleted()) {
Hashtable tableItem = new Hashtable();
Image img = null;
try {
if (!storage.exists(image.getFileName())) {
img = placeholderImg;
tableItem.put("icon", img.scaled(imgHeight, -1));
} else {
InputStream is = storage.createInputStream(image.getFileName());
img = Image.createImage(is);
// tableItem.put("icon", img.scaled(imgHeight, -1));
is.close();
System.err.println("WITH FILENAME stuff");
}
tableItem.put("emblem", image.getFileName());
tableItem.put("sort", image.getSort());
} catch (IOException e) {
e.printStackTrace();
}
vector.add(tableItem);
}
}
System.err.println("AND GC stuff is somewhere here");
cmp.setModel(new com.codename1.ui.list.DefaultListModel(vector));
return true;
}
我什至尝试在 InputStream 上执行 close() 和 Util.cleanup(is) 来检查问题出在哪里。通常我的实现是 Storage.getInstance() 对于这个方法中的每个调用。
当我在其他部分评论 Inputstream is
之后的行时,我没有在控制台中收到这样的消息
所以我在这里问的问题是这些方法是否存在误用,或者我是否可以忽略它?
该警告意味着您没有关闭数据库中的游标,只是让 GC 为您收集它。它与您发布的代码无关,与使用 database/SQL 包的代码有关。
此警告是为了保护您免受 iOS 的影响,其中代码 必须 正确关闭连接,因为 iOS 的 sqlite 版本是 REALLY 对线程访问敏感,如果被两个线程访问会崩溃。 GC 终结器在单独的线程中执行,因此依赖这些对象的终结可能会使您的应用程序崩溃。
我这里有一个奇怪的问题,它告诉我一些数据库对象被释放了,尽管在下面显示的方法中至少没有数据库连接。
控制台输出:
SOMETIMES I DROP GC stuff
WITH FILENAME stuff
WITH FILENAME stuff
WITH FILENAME stuff
**** WARNING! Database object was released by the GC without being closed first! This might cause crashes on iOS *****
**** WARNING! Database object was released by the GC without being closed first! This might cause crashes on iOS *****
**** WARNING! Database object was released by the GC without being closed first! This might cause crashes on iOS *****
WITH FILENAME stuff
WITH FILENAME stuff
WITH FILENAME stuff
AND GC stuff is somewhere here
以及对应的方法
@Override
protected boolean initListModelPhotoList(List cmp) {
Integer imgHeight = Display.getInstance().getDisplayHeight() / 10;
Image placeholderImg = fetchResourceFile().getImage("camera_placeholder.png");
System.err.println("SOMETIMES I DROP GC stuff");
Storage storage = Storage.getInstance();
Vector vector = new Vector();
for (xyz.model.Image image : images) {
if (!image.getDeleted()) {
Hashtable tableItem = new Hashtable();
Image img = null;
try {
if (!storage.exists(image.getFileName())) {
img = placeholderImg;
tableItem.put("icon", img.scaled(imgHeight, -1));
} else {
InputStream is = storage.createInputStream(image.getFileName());
img = Image.createImage(is);
// tableItem.put("icon", img.scaled(imgHeight, -1));
is.close();
System.err.println("WITH FILENAME stuff");
}
tableItem.put("emblem", image.getFileName());
tableItem.put("sort", image.getSort());
} catch (IOException e) {
e.printStackTrace();
}
vector.add(tableItem);
}
}
System.err.println("AND GC stuff is somewhere here");
cmp.setModel(new com.codename1.ui.list.DefaultListModel(vector));
return true;
}
我什至尝试在 InputStream 上执行 close() 和 Util.cleanup(is) 来检查问题出在哪里。通常我的实现是 Storage.getInstance() 对于这个方法中的每个调用。
当我在其他部分评论 Inputstream is
之后的行时,我没有在控制台中收到这样的消息
所以我在这里问的问题是这些方法是否存在误用,或者我是否可以忽略它?
该警告意味着您没有关闭数据库中的游标,只是让 GC 为您收集它。它与您发布的代码无关,与使用 database/SQL 包的代码有关。
此警告是为了保护您免受 iOS 的影响,其中代码 必须 正确关闭连接,因为 iOS 的 sqlite 版本是 REALLY 对线程访问敏感,如果被两个线程访问会崩溃。 GC 终结器在单独的线程中执行,因此依赖这些对象的终结可能会使您的应用程序崩溃。