android – RealmError:Realm内存不足
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了android – RealmError:Realm内存不足,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4206字,纯文字阅读大概需要7分钟。
内容图文
我使用Realm 3.0.0作为我的Android应用程序的数据库.这就像一个问卷调查应用程序,用户在应用程序中导航很多.当我连续使用应用程序(来回)时,我收到以下错误:
Fatal Exception: io.realm.exceptions.RealmError: Unrecoverable error. mmap() failed: Out of memory size: 1073741824 offset: 0 in /Users/cm/Realm/realm-java/realm/realm-library/src/main/cpp/io_realm_internal_SharedRealm.cpp line 109
at io.realm.internal.SharedRealm.nativeGetSharedRealm(SharedRealm.java)
at io.realm.internal.SharedRealm.(SharedRealm.java:187)
at io.realm.internal.SharedRealm.getInstance(SharedRealm.java:229)
at io.realm.internal.SharedRealm.getInstance(SharedRealm.java:204)
at io.realm.RealmCache.createRealmOrGetFromCache(RealmCache.java:124)
at io.realm.Realm.getDefaultInstance(Realm.java:210)
现在我知道这主要原因不是关闭Realm实例.但我已经多次检查过了.而且我很肯定我关闭了每一个打开的实例.
该应用程序有许多活动和片段,所有活动和片段都在其onCreate上获得Realm实例并在其onDestroy上关闭它.还有其他后台网络作业用于上载获取Realm实例的数据.这些作业在完成运行或取消时关闭其Realm实例.
以上所有通过Dagger 2通过注入得到它们的Realm实例:
@Provides
@Nullable
static Realm realm(@Nullable RealmConfiguration configuration) {
if (configuration != null) {
Realm.setDefaultConfiguration(configuration);
return Realm.getDefaultInstance();
}
return null;
}
配置也在同一个Dagger模块中提供.
更具体地说,问卷由ViewPager中显示的许多问题片段组成.每个片段都注入了一个领域.给定问题片段中的许多交互将数据写入数据库(一些异步,一些阻塞).这些片段还在onResume上查询数据库以获取其更新的数据.其中一些数据也通过realm.copyFromRealm()从Realm中复制出来.现在,在发生这些情况的任何给定时间,上传作业很可能正在运行并从数据库读取数据并将其上载到服务器.上传作业完成后,它会写入数据库.
我想我可以在给定时刻在UI线程上拥有最多7-12个片段/活动. 0-3其他线程上的0-6个其他引用(后台作业).
此外,我通过Realm.compactRealm(realmConfiguration)在每个应用程序启动时压缩我的领域数据库(可能作为一个单独的问题,这似乎并不是一贯的工作).
上面我试图描述性地描述我的Realm用法,而不是详细介绍.现在我的问题是,当用户过度使用应用程序(在活动/片段之间往返(领域注入数据库读取查询),上传数据(领域注入数据库读取和写入查询))时,我得到上面发布的内存不足错误.
我也在使用泄漏金丝雀,它没有检测到任何泄漏. (不确定它是否可以)
我是否以不应该使用的方式使用Realm?我应该关闭Real实例onPause而不是onDestroy吗?我是否应该在一个活动中只有一个领域实例并且所有它都是fragmetns(在我的情况下最多为5个)使用这个实例?我可以在我的应用程序中进行哪些更改,也许我的应用程序架构可以解决此问题?
我感谢任何帮助,试图解决这个问题.
编辑:我在我的后台线程中分享领域开放逻辑.
我的所有作业共享相同的领域用法,如下所示:
领域通过以下方式懒洋洋地注入:
@Inject protected transient Lazy< Realm> lazyRealm;
领域对象引用保存在私有瞬态Realm领域;领域.我正在使用Android Priority Job Queue.添加作业时:
@Override
public void onAdded() {
realm = lazyRealm.get();
realm.executeTransaction(realm1 -> {
//write some stuff into realm
});
realm.close();
}
当作业运行时,realm会被检索一次,并且此方法的每个可能结束都会调用realm.close()
@Override public void onRun() throws Throwable {
synchronized (syncAdapterLock) {
realm = lazyRealm.get();
Answer answer = realm.where(Answer.class).equalTo(AnswerQuery.ID, answerId).findFirst();
if (answer == null) {
realm.close();
throw new RealmException("File not found");
}
final File photoFile = new File(answer.getFilePath());
final Response response = answerService.uploadPhotoAnswer(answerId, RequestBody.create(MediaType.parse("multipart/form-data"), photoFile)).execute();
if (!response.isSuccessful()) {
realm.close();
throw new HttpError(statusCode);
}
realm.executeTransaction(realm1 -> {
answer.setSyncStatus(SyncStatus.SYNCED.getCode());
});
}
realm.close();
}
}
正如您所看到的,就我而言,这些后台线程确实正确地关闭了它们的领域实例.
解决方法:
虽然我的所有后台任务都确实调用了realm.close(),但其中一个人在其生命周期中称它为时已晚.那是我的GPSService,这是一个后台服务.问题是GPS服务在作为Android服务推出时初始化,很少被销毁.我正在onCreate上注入一个领域实例并将其关闭onDestroy.在@EpicPandaForce的评论之后,阅读他关于正确使用领域的文章.我意识到这是泄漏的原因.一个非looper线程在很长一段时间内都保持一个开放的域引用,因此,每次写入事务发生时,mmap都会膨胀.现在我每次运行服务时都移动了领域get / close,我的问题就解决了.
我带走的是,需要非常精细地处理后台线程域访问.感谢您的快速回复和帮助!
内容总结
以上是互联网集市为您收集整理的android – RealmError:Realm内存不足全部内容,希望文章能够帮你解决android – RealmError:Realm内存不足所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。