0

我正在尝试对现有数据库进行批量插入,但出现以下异常:

线程“GC-Monitor”中的异常 java.lang.OutOfMemoryError:java.util.Arrays.copyOf(Arrays.java:2245) 处 java.util.Arrays.copyOf(Arrays.java:2219) 处的 Java 堆空间。 util.ArrayList.grow(ArrayList.java:242) 在 java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:216) 在 java.util.ArrayList.ensureCapacityInternal(ArrayList.java:208) 在 java.util.ArrayList.add (ArrayList.java:440) 在 java.util.Formatter.parse(Formatter.java:2525) 在 java.util.Formatter.format(Formatter.java:2469) 在 java.util.Formatter.format(Formatter.java: 2423) at java.lang.String.format(String.java:2792) at org.neo4j.kernel.impl.cache.MeasureDoNothing.run(MeasureDoNothing.java:64) 失败:事务被标记为成功,但无法提交事务因此回滚。

这是我的插入代码的结构:

public void parseExecutionRecordFile(Node episodeVersionNode, String filePath, Integer insertionBatchSize) throws Exception {
        Gson gson = new Gson();
        BufferedReader reader = new BufferedReader(new FileReader(filePath));
        String aDataRow = "";
        List<ExecutionRecord> executionRecords = new LinkedList<>();

        Integer numberOfProcessedExecutionRecords = 0;
        Integer insertionCounter = 0;
        ExecutionRecord lastProcessedExecutionRecord = null;
        Node lastProcessedExecutionRecordNode = null;

        Long start = System.nanoTime();
        while((aDataRow = reader.readLine()) != null) {
            JsonReader jsonReader = new JsonReader(new StringReader(aDataRow));
            jsonReader.setLenient(true);
            ExecutionRecord executionRecord = gson.fromJson(jsonReader, ExecutionRecord.class);
            executionRecords.add(executionRecord);

            insertionCounter++;

            if(insertionCounter == insertionBatchSize || executionRecord.getType() == ExecutionRecord.Type.END_MESSAGE) {
                lastProcessedExecutionRecordNode = appendEpisodeData(episodeVersionNode, lastProcessedExecutionRecordNode, executionRecords, lastProcessedExecutionRecord == null ? null : lastProcessedExecutionRecord.getTraceSequenceNumber());
                executionRecords = new LinkedList<>();
                lastProcessedExecutionRecord = executionRecord;
                numberOfProcessedExecutionRecords += insertionCounter;
                insertionCounter = 0;
            }
        }
    }

public Node appendEpisodeData(Node episodeVersionNode, Node previousExecutionRecordNode, List<ExecutionRecord> executionRecordList, Integer traceCounter) {
        Iterator<ExecutionRecord> executionRecordIterator = executionRecordList.iterator();

        Node previousTraceNode = null;
        Node currentTraceNode = null;
        Node currentExecutionRecordNode = null;

        try (Transaction tx = dbInstance.beginTx()) {
            // some graph insertion

            tx.success();
            return currentExecutionRecordNode;
        }
    }

所以基本上,我从一个文件(大约 20,000 个对象)中读取 json 对象,然后每 10,000 条记录将其插入 neo4j。如果文件中只有 10,000 个 JSON 对象,那么它可以正常工作。但是当我有 20,000 时,它会抛出异常。

在此先感谢,任何帮助将不胜感激!

4

2 回答 2

2

如果有 10000 个对象有效,只需尝试至少复制堆内存。看看以下网站: http: //neo4j.com/docs/stable/server-performance.html

wrapper.java.maxmemory选项可以解决您的问题。

于 2015-08-07T03:54:29.877 回答
1

当您还插入几个 k 属性时,所有 tx 状态都将保存在内存中。所以我认为 10k 批量大小对于这么多的堆来说就很好了。

你也不要关闭你的 JSON 阅读器,所以它可能会在StringReader里面徘徊。

您还应该使用按ArrayList您的批量大小初始化并使用list.clear()而不是重新分配/重新分配。

于 2015-08-11T12:50:37.520 回答