-3

Jenkins で build.xml を使用して Junit テスト ケースを実行しています。特定のテスト ケースを実行すると、以下のエラーが発生します。

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
<title>Error 500 Java heap space</title>
</head>
<body><h2>HTTP ERROR 500</h2>
<p>Problem accessing /url. Reason:
<pre>    Java heap space</pre></p><h3>Caused by:</h3><pre>java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:2882)
    at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:100)
    at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:390)
    at java.lang.StringBuilder.append(StringBuilder.java:119)
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
    at java.lang.Long.parseLong(Long.java:410)
    at java.lang.Long.valueOf(Long.java:525)
    at org.codehaus.jettison.mapped.DefaultConverter.convertToJSONPrimitive(DefaultConverter.java:39)
    at org.codehaus.jettison.mapped.MappedNamespaceConvention.convertToJSONPrimitive(MappedNamespaceConvention.java:282)
    at org.codehaus.jettison.mapped.MappedXMLStreamWriter$JSONPropertyObject.withProperty(MappedXMLStreamWriter.java:153)
    at org.codehaus.jettison.mapped.MappedXMLStreamWriter$JSONProperty.withProperty(MappedXMLStreamWriter.java:66)
    at org.codehaus.jettison.mapped.MappedXMLStreamWriter.writeEndElement(MappedXMLStreamWriter.java:247)
    at com.sun.xml.bind.v2.runtime.output.XMLStreamWriterOutput.endTag(XMLStreamWriterOutput.java:144)
    at com.sun.xml.bind.v2.runtime.output.XmlOutputAbstractImpl.endTag(XmlOutputAbstractImpl.java:120)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.leafElement(XMLSerializer.java:326)
    at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl$StringImplImpl.writeLeafElement(RuntimeBuiltinLeafInfoImpl.java:1041)
    at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl$StringImplImpl.writeLeafElement(RuntimeBuiltinLeafInfoImpl.java:1020)
    at com.sun.xml.bind.v2.runtime.reflect.TransducedAccessor$CompositeTransducedAccessorImpl.writeLeafElement(TransducedAccessor.java:252)
    at com.sun.xml.bind.v2.runtime.property.SingleElementLeafProperty.serializeBody(SingleElementLeafProperty.java:121)
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:340)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:696)
    at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:152)
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:340)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:696)
    at com.sun.xml.bind.v2.runtime.property.ArrayElementNodeProperty.serializeItem(ArrayElementNodeProperty.java:65)
    at com.sun.xml.bind.v2.runtime.property.ArrayElementProperty.serializeListBody(ArrayElementProperty.java:168)
    at com.sun.xml.bind.v2.runtime.property.ArrayERProperty.serializeBody(ArrayERProperty.java:155)
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:340)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsSoleContent(XMLSerializer.java:593)
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(ClassBeanInfoImpl.java:324)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:494)
    at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:315)

以下は、junit テストケース build.xml を実行するために使用する build.xml コードです。

<target name="runTests">
  <junit fork="yes" forkmode="once" printsummary="yes" dir="${basedir}" includeantruntime="yes" failureproperty="failureTest" maxmemory="1024m" jvm="">
  <jvmarg value="-XX:MaxPermSize=512M"/>
  <jvmarg value="-Dlog4j.configuration=log4j.properties"/>

ただし、このエラーは特定のシステムでのみ発生しており、すべての環境で発生しているわけではありません。どうすればこれを取り除くことができますか?

4

3 に答える 3

2

テストを見ずにあなたを助けるのは本当に難しいですが、私の推測では、特に文字列の構築を伴う場合、あなたが扱っているものは何でも大きいと思います. いくつかの提案が役立ちます:

  1. を使用しStringBuilder classて応答を作成してみてください。大きな文字列を作成するときに「+」記号を使用するのとは大きな違いがあることに気付きました。
  2. eclipse.ini で Eclipse に使用できるメモリを増やします。適切な説明は、このリンクにあります。

メモリ設定を変更する代わりに、コードを調べて変更しようとします。JVM に割り当てられるメモリを増やすことができる限り、初期メモリ設定が小さいのには理由があります。これは、開発者がメモリ ランナウェイ プログラムを作成するだけでなく、メモリに制約のある環境を含め、ほとんどの環境で実行されるプログラムの設計に注意を払う必要があるためだと思います。

于 2013-02-25T14:52:36.460 に答える
2

OOM のスタックトレースから開始することは、ほとんどの場合、誤解を招く可能性があります。ヒープがほぼいっぱいになると、オブジェクトの割り当てが失敗する可能性があるからです。

ヒープを増やすと役立つかもしれませんが、ユースケース (コメントで述べたようにいくつかの検証をテストする) は、数ギグの RAM を必要としないように思えます。

迅速な回答が必要な場合は、ツールを使用してください。JVM arg: <jvmarg value="-XX:+HeapDumpOnOutOfMemoryError"/>を含めます。ヒープがダンプされたら、それをEclipse メモリ アナライザー ツールで開き、何がメモリを消費しているかを確認します。これは、問題を数分で特定できる非常に優れたツールです (単純なケースの場合)。

1 つのヒント: テスト クラスが を使用しSpringJUnit4ClassRunnerてテスト コンテキストをロードする場合、Spring は実行中にロードされたすべてのコンテキストをキャッシュします。さまざまなコンテキストで多数の統合テストがある場合、その 512m ヒープを使い果たす可能性が高くなります。

于 2013-02-25T15:03:23.413 に答える
0

ヒープスペースを増やしてみてください。

于 2013-02-25T14:44:46.440 に答える