我需要将一个MySQL数据库中的1亿多行记录加载到内存中。我的Java程序失败,java.lang.OutOfMemoryError: Java heap space
因为我的机器中有8GB RAM,并且我的JVM选项中给出了-Xmx6144m。
这是我的代码
public List<Record> loadTrainingDataSet() {
ArrayList<Record> records = new ArrayList<Record>();
try {
Statement s = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY);
s.executeQuery("SELECT movie_id,customer_id,rating FROM ratings");
ResultSet rs = s.getResultSet();
int count = 0;
while (rs.next()) {
任何想法如何克服这个问题?
我碰到了这篇文章 ,以及根据下面的评论更新了我的代码。看来我能够以相同的-
Xmx6144m量将数据加载到内存中,但是需要很长时间。
这是我的代码。
...
import org.apache.mahout.math.SparseMatrix;
...
@Override
public SparseMatrix loadTrainingDataSet() {
long t1 = System.currentTimeMillis();
SparseMatrix ratings = new SparseMatrix(NUM_ROWS,NUM_COLS);
int REC_START = 0;
int REC_END = 0;
try {
for (int i = 1; i <= 101; i++) {
long t11 = System.currentTimeMillis();
REC_END = 1000000 * i;
Statement s = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
java.sql.ResultSet.CONCUR_READ_ONLY);
s.setFetchSize(Integer.MIN_VALUE);
ResultSet rs = s.executeQuery("SELECT movie_id,customer_id,rating FROM ratings LIMIT " + REC_START + "," + REC_END);//100480507
while (rs.next()) {
int movieId = rs.getInt("movie_id");
int customerId = rs.getInt("customer_id");
byte rating = (byte) rs.getInt("rating");
ratings.set(customerId,movieId,rating);
}
long t22 = System.currentTimeMillis();
System.out.println("Round " + i + " completed " + (t22 - t11) / 1000 + " seconds");
rs.close();
s.close();
}
} catch (Exception e) {
System.err.println("Cannot connect to database server " + e);
} finally {
if (conn != null) {
try {
conn.close();
System.out.println("Database connection terminated");
} catch (Exception e) { /* ignore close errors */ }
}
}
long t2 = System.currentTimeMillis();
System.out.println(" Took " + (t2 - t1) / 1000 + " seconds");
return ratings;
}
要加载前100,000行,需要2秒钟。加载第29
100,000行需要46秒。我花了太多时间在中间停止了该过程。这些时间是否可接受?有没有办法提高此代码的性能?我在8GB RAM
64位Windows计算机上运行此文件。
亿条记录意味着,每条记录最多可能占用50个字节,以适合6 GB+一些额外空间用于其他分配。在Java中,50个字节是什么,Object[]
每个元素仅占用32个字节。您必须找到一种方法来立即在while (rs.next())
循环中使用结果,而不是完全保留它们。
在服务器重置缓存数据保存在磁盘存储后。但在服务器启动后不使用缓存数据。所以我想加载磁盘存储内容到memory.How做到这一点?在这个堆栈问题加载EhCache磁盘存储内容到内存中使用BootstrapCacheLoaderFactory但不为我出现。
如EhCache留档所述: 实际上,这意味着持久性内存中缓存将启动,其所有元素都将在磁盘上。[...]因此,Ehcache设计不会在启动时将它们全部加载到内存中,而是根据需要懒惰地加载它们。 我希望内存缓存启动时将所有元素都存储在内存中,我该如何实现? 这是因为我们的网站对缓存执行了大量的访问,所以我们第一次访问网站时,它的响应时间非常长。
问题内容: 我想知道如何将字节数组加载到 内存 URLClassLoader中?字节数组是jar文件的解密字节(如下所示)! 大多数内存类加载器都使用ClassLoader而不是URLClassLoader!我需要它使用URLClassLoader。 谢谢! 问题答案: 我将在这里发布我过去做过的实现: 我的自定义ClassLoader:
虽然我有重复问题的风险,但我还没有找到配置的解决方案。 我正在尝试将rJava加载到RStudio中。 我使用的是最新的Mac OS x,Rstudio版本只有几个月的历史,我刚刚安装了JDK x64 12.0.1 rJava的版本是0.9-11 执行时: 我面临着通常的情况: 错误:“rJava”的包或命名空间加载失败:。“rJava”的loadNamespace()中的onLoad失败,详细信
问题内容: 如果已经将整个.class文件序列化为byte [],并假定该类的名称已知(与byte []一起传递),则如何转换byte []-> Class->然后将其加载到JVM,以便以后可以通过调用Class.forName()使用它? 注意: 之所以这样做,是因为我将.class发送到另一台主机,而主机的JVM不知道此.class。 问题答案: 我现在在测试中实际上正在使用类似的方法,将一组