Javaの定数の参照がメモリリークの原因は?

dstsoft.net:

JVM jstatはコマンド:

  jstat -gcutil 14378 2000 20
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   
  8.04   0.00  87.61   9.06  96.45  94.34    702   13.804     8    2.521   16.325

コードブロックにEclipseのメモリ分析移動します。

public class MicrosoftConstant {

/**
 * TODO TTS 请求头设置
 */
public static final List<Header> TTS_REQUEST_HEADERS = new ArrayList<Header>(){
    {
        add(new BasicHeader("Content-Type", "application/ssml+xml"));
        add(new BasicHeader("X-Microsoft-OutputFormat", "xxx"));
        add(new BasicHeader("X-Search-AppId", "xxx"));
        add(new BasicHeader("X-Search-ClientID", "xxx"));
        add(new BasicHeader("User-Agent", "xxx"));
        add(new BasicHeader("Accept", "*/*"));
    }
};

}

コードブロックを使用して定数:

List<Header> headers = MicrosoftConstant.TTS_REQUEST_HEADERS;
    headers.add(new BasicHeader("Ocp-Apim-Subscription-Key", microsoftConfig.getAppKey()));
    headers.add(new BasicHeader("Authorization", "Bearer " + authToken));
    InputStream audioStream = null;

        HttpEntity httpEntity = httpApiService.doPost(microsoftConfig.getTtsUrl(), body.getBytes(), headers);

インターフェースは、アクセスの数が多い時にメモリを解放しません。

私はこの問題を解決するための方法がわかりません。誰もが解決策を提供することができますか?

マークRotteveel:

あなただけのメモリリークが、また、可能なセキュリティリークを持っていません。問題は、あなたが要求ごとに、あなたがいることで追加リストにヘッダをTTS_REQUEST_HEADERSこの手段各要求で、リストが成長し、それが縮小したことがないということ。

また、あなたが使用「ダブルブレースの初期化」アンチパターンが、問題のそれほどではありません、この場合には。

さらに悪いことに、それは実際の要求は特定のヘッダに意図せずに以前の要求に関する情報が漏れる可能性が複数回(これはHTTPクライアントが繰り返しヘッダと何をするかによって異なります)、繰り返してもよいことを意味します。

この問題を解決するにはすることです、コピー、リストのコピーにあなたの要求の特定のヘッダを追加し、要求を実行するためにコピーを使用しています。あなたが意図せずに一定にリストを変更しないことには、必ずそれは(方法は、それが実際に一定であることを)変更できませんします。

これを行うには、例えば、変更不可能なリストとしてリストを定義します。

public static final List<Header> TTS_REQUEST_HEADERS = 
        Collections.unmodifiableList(Arrays.asList(
                new BasicHeader("Content-Type", "application/ssml+xml"),
                new BasicHeader("X-Microsoft-OutputFormat", "xxx"),
                new BasicHeader("X-Search-AppId", "xxx"),
                new BasicHeader("X-Search-ClientID", "xxx"),
                new BasicHeader("User-Agent", "xxx"),
                new BasicHeader("Accept", "*/*")));

または、Javaの9のために、より高い使用しましたList.of

public static final List<Header> TTS_REQUEST_HEADERS = List.of(
        new BasicHeader("Content-Type", "application/ssml+xml"),
        new BasicHeader("X-Microsoft-OutputFormat", "xxx"),
        new BasicHeader("X-Search-AppId", "xxx"),
        new BasicHeader("X-Search-ClientID", "xxx"),
        new BasicHeader("User-Agent", "xxx"),
        new BasicHeader("Accept", "*/*"));

あなたの要求コードはその後になります:

// Copy the standard list of headers for this request
List<Header> headers = new ArrayList<>(MicrosoftConstant.TTS_REQUEST_HEADERS);
headers.add(new BasicHeader("Ocp-Apim-Subscription-Key", microsoftConfig.getAppKey()));
headers.add(new BasicHeader("Authorization", "Bearer " + authToken));
InputStream audioStream = null;

HttpEntity httpEntity = httpApiService.doPost(microsoftConfig.getTtsUrl(), body.getBytes(), headers);

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=373384&siteId=1