java - 数据库对象在没有先关闭的情况下被GC释放

标签 java garbage-collection codenameone

我在这里遇到一个奇怪的问题,显示一些数据库对象已在下面所示的方法中释放,但至少没有数据库连接。

控制台输出:

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()。

当我在 else 部分中注释 Inputstream is 之后的行时,我在控制台中没有收到这样的消息

所以我在这里问的问题是是否存在误用这些方法或者我是否可以忽略它?

最佳答案

该警告意味着您没有关闭数据库中的游标,只是让 GC 为您收集它。它与您发布的代码无关,与使用数据库/SQL 包的代码有关。

此警告是为了保护您免受 iOS 的影响,其中代码必须正确关闭连接,因为 iOS 版本的 sqlite 对线程访问非常敏感,如果被两个线程访问,则会崩溃线程。 GC 终结器在单独的线程中执行,因此依赖这些对象的终结可能会使您的应用程序崩溃。

关于java - 数据库对象在没有先关闭的情况下被GC释放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38980128/

相关文章:

java - 设置-XX :+DisableExplicitGC in production: what could go wrong?

java - 一个应用程序显示无法执行 dex : GC overhead limit exceeded GC overhead limit exceeded in eclipse

java - 是否可以使用代号一将 eclipse 中的 android 应用程序转换为 ios Rim 窗口?

java - 多次运行同一个 jar 文件会相互影响吗?

java - 使用 Java 对用户输入的字符进行计数时出错

java.lang.OutOfMemoryError : Compressed class space 错误

ios - 代号一个日期在iOS和Android上给出不同的结果

java - 如何在java中从SQLite获取日期值

java - Java EE 上的通知样式 Google 日历

ios - NSMutableArray 全局