2017-01-12 46 views
0

私は、ソースコードからテストフレームワークの使用法を抽出するために(例えば、assertEqualsを検出してアサート密度を測定する)かなり大規模な(1000のプロジェクト)分析を行っています。このため、コメントアウトされた声明は考慮したくありません。私は、Javaのコメントを交換するには、次の正規表現で、この方法を実行していますReplaceAll regexによってJava OutOfMemoryErrorが発生する

public static CharSequence replaceAllRegexInFile(CharSequence input, String regex) { 
    if (regex == null || input == null) { 
     return input; 
    } 
    Pattern pattern = Pattern.compile(regex); 
    return pattern.matcher(input).replaceAll(""); 
} 

(\/\*([\S\s]+?)\*\/|(?s)/\*.*?\*/)". 

私はでReplaceAllは多くのことを割り当てていることを十分認識していますこれを行うために、私は次のメソッドを持っています最終的な結果を集約して返しながら中間結果を返します。確かに、私はreplaceを使うことに頼ることができますが、これは私がコメントを置き換えるために正規表現を使用することを許可しません。

私はすべてのファイルとすべてのプロジェクトを私のマシン全体で同時にストリーミングしているので、なぜヒープスペースエラーがスローされるのかが分かります。確かにこれは、多くのリソースを使用していますが、私は正規表現の置き換えはdefinitelly要件であるため、私の問題のための代替ソリューションを見つけることができません。

ご意見をいただければ幸いです。

Exception in thread "main" java.lang.OutOfMemoryError 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) 
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423) 
    at java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:598) 
    at java.util.concurrent.ForkJoinTask.reportException(ForkJoinTask.java:677) 
    at java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:735) 
    at java.util.stream.ReduceOps$ReduceOp.evaluateParallel(ReduceOps.java:714) 
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233) 
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) 
    at AnalysisRunner.startAnalysis(AnalysisRunner.java:33) 
    at AnalysisRunner.main(AnalysisRunner.java:26) 
Caused by: java.lang.OutOfMemoryError: Java heap space 
    at java.util.Arrays.copyOf(Arrays.java:3332) 
    at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124) 
    at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:541) 
    at java.lang.StringBuffer.append(StringBuffer.java:350) 
    at java.util.regex.Matcher.appendReplacement(Matcher.java:888) 
    at java.util.regex.Matcher.replaceAll(Matcher.java:955) 
    at Business.RegexService.replaceAllRegexInFile(RegexService.java:64) 
    at Business.FrameWorkDetectionService.extractAllResultsForFile(FrameWorkDetectionService.java:58) 
    at Business.FrameWorkDetectionService.lambda$extractFrameworkDependencies$0(FrameWorkDetectionService.java:39) 
    at Business.FrameWorkDetectionService$$Lambda$19/1175339539.apply(Unknown Source) 
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) 
    at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374) 
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) 
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) 
    at java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:747) 
    at java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:721) 
    at java.util.stream.AbstractTask.compute(AbstractTask.java:316) 
    at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731) 
    at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289) 
    at java.util.concurrent.ForkJoinPool.helpComplete(ForkJoinPool.java:1870) 
    at java.util.concurrent.ForkJoinPool.awaitJoin(ForkJoinPool.java:2045) 
    at java.util.concurrent.ForkJoinTask.doInvoke(ForkJoinTask.java:404) 
    at java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:734) 
    at java.util.stream.ReduceOps$ReduceOp.evaluateParallel(ReduceOps.java:714) 
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233) 
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) 
    at Business.FrameWorkDetectionService.extractFrameworkDependencies(FrameWorkDetectionService.java:39) 
    at Business.FrameWorkDetectionService.detectFrameworks(FrameWorkDetectionService.java:26) 
    at Business.FrameworkService.projectResults(FrameworkService.java:59) 
    at AnalysisRunner$$Lambda$13/1712669532.apply(Unknown Source) 
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) 
    at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175) 

まだ私は同時にたくさんのファイルにすべてのコメントを置き換えることができます。このくらいのヒープ領域を割り当てません代替ソリューションがあります:

あなたは、以下のスタックトレースを見つけることができますか?

すべてのヘルプは大歓迎です!

+4

非効率な正規表現のパターンを交互に使用すると、通常の問題です。 [RegexをCスタイルの複数行のコメントに一致させる](http://stackoverflow.com/a/36328890/3832970)の正規表現を使用してください。ところで、 '/ \ *([\ S \ s] +?)\ * /'は '(?s)/\*.*?\*/と同じテキストにマッチします。 ' –

答えて

1

これは答えよりも大きなコメントのようですが、フォーマットが豊富なので答えとして投稿すると思います。

あなたの正規表現は、このような大きなメモリエラーを引き起こしている可能性があります良いパフォーマンスがありません。

enter image description here

私はこのことから理解することはあなただけのブロックコメントを取り除きたいということです。例えば、これはあなたの正規表現が持っている図です。だから、あなたの正規表現にはさまざまな問題があります。最も重要なのは、まったく同じことをするために異なるパターンがあることです。したがって、それらのうちの1つを使用するだけで、グループや交代をキャプチャしたり、彼らが好き:

\/\*[\S\s]+?\*\/". <--- I removed the capturing group to make it more efficient, since you didn't need it 
or 
(?s)/\*.*?\*/". 

enter image description here

あなたが見ることができるように、正規表現パターンは、はるかに効率的である、それは2つのパターン、また2つのキャプチャグループでも非常に高価であり、交代を持っていません。

は、Javaを必要としない場合はとにかく、私は(場所に置き換え)-iフラグでsedのようにこれらの置き換えを実行するためのより良いツールがあると思い

しかし、あなたはまだあなたの正規表現を使用したい場合

2

Javaは、アプリに十分なメモリを割り当てることはできません。あなたは、例えば、-Xmx-Xmsのフラグを使用して割り当てられた初期および最大メモリを増やすことを試みることができます。

java -Xmx2048m -Xms512m yourApp 

アプリケーションが鎮圧されませんので、これらのパラメータを調整します。

割り当てられたメモリを変更すると、その後、アプリケーションの実行中にjmap -heap:format=b <process-id>を使用して、ヒープ・ダンプを作成してみてください役立つメモリ・アナライザのいくつかの種類で開いていない場合は、java -X

を実行して、すべての可能なパラメータを見ることができます(たとえばhttp://www.eclipse.org/mat/用) 。たぶん、コードの他の部分にいくつかのメモリリークがあると、これはそれらを検出します

関連する問題