UTF8 - CharsetEncoder #coding() - 无限循环

时间:2014-01-07 20:26:39

标签: java character-encoding playframework-2.2 jongo

我们有一个Play 2.2.1应用程序正在使用插件jongo来管理MongoDB访问和对象映射。这个插件使用一个名为bson4jackson的库来为Jackson JSON处理器添加对BSON的支持。

我们可以处理数百MB的UTF8数据,但是随机地,我们有一个永不结束的线程,占用了CPU的一个线程的100%。 使用相同的数据集,可能会发生错误。

这是线程的调用堆栈:

application-akka.actor.default-dispatcher-12 [RUNNABLE]
de.undercouch.bson4jackson.io.DynamicOutputBuffer.putUTF8(int, String)
de.undercouch.bson4jackson.io.DynamicOutputBuffer.putUTF8(String)
de.undercouch.bson4jackson.BsonGenerator._writeCString(String)
de.undercouch.bson4jackson.BsonGenerator._writeString(String)
de.undercouch.bson4jackson.BsonGenerator.writeString(String)
com.fasterxml.jackson.databind.ObjectWriter.writeValue(OutputStream, Object)
org.jongo.marshall.jackson.JacksonEngine.marshall(Object)
org.jongo.Insert.marshallDocument(Object)
org.jongo.Insert.createDBObjectToInsert(Object)
org.jongo.Insert.save(Object)
org.jongo.MongoCollection.save(Object)
models.audits.PageEntityCollection.save(PageEntity)
services.audit.PageBean.finish()
services.audit.PageBean.auditChangeState(AuditState)
services.audit.dispatcher.SchedulerAPI.schedule(PageBean)
services.audit.dispatcher.PageAuditManager.startAudit(String, String, String, String,    String)
controllers.HARReceiver.launchAudit(JsonNode, String)
controllers.HARReceiver$1.run()
akka.dispatch.TaskInvocation.run()
akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec()
scala.concurrent.forkjoin.ForkJoinTask.doExec()
scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinTask)
scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool$WorkQueue)
scala.concurrent.forkjoin.ForkJoinWorkerThread.run()

该方法的代码如下: Link to the class

    public int putUTF8(int pos, String s) {
            ByteBuffer minibb = null;

            CharsetEncoder enc = getUTF8Encoder();
            CharBuffer in = CharBuffer.wrap(s);

            int pos2 = pos;
            ByteBuffer bb = getBuffer(pos2);
            int index = pos2 % _bufferSize;
            bb.position(index);

            while (in.remaining() > 0) {
                    CoderResult res = enc.encode(in, bb, true);

                    //flush minibb first
                    if (bb == minibb) {
                            bb.flip();
                            while (bb.remaining() > 0) {
                                    putByte(pos2, bb.get());
                                    ++pos2;
                            }
                    } else {
                            pos2 += bb.position() - index;
                    }

                    if (res.isOverflow()) {
                            if (bb.remaining() > 0) {
                                    //exceeded buffer boundaries; write to a small temporary buffer
                                    if (minibb == null) {
                                            minibb = ByteBuffer.allocate(4);
                                    }
                                    minibb.rewind();
                                    bb = minibb;
                                    index = 0;
                            } else {
                                    bb = getBuffer(pos2);
                                    index = pos2 % _bufferSize;
                                    bb.position(index);
                            }
                    } else if (res.isError()) {
                            try {
                                    res.throwException();
                            } catch (CharacterCodingException e) {
                                    throw new RuntimeException("Could not encode string", e);
                            }
                    }
            }

            adaptSize(pos2);
            return pos2 - pos;
    }

我们发现该主题始终在运行并保持while (in.remaining() > 0),因为我们看到了重复调用encode()方法。

我们真的不明白为什么会这样。 我们的团队中没有关于I / O的主要技能,我们很乐意得到问题的来源或调试方法。

0 个答案:

没有答案
相关问题