このパッチは、一部のHive出力がbeelineコンソールに出力されない問題を修正するために使用されます:
https ://issues.apache.org/jira/browse/HIVE-16061
漏れたオブジェクトを見つけます
ファイルをダンプした後、リークされたオブジェクトがこのマップの
クエリに対応するキーであることが簡単にわかります
。正常に削除されました。クライアントが再接続して多数のキーを追加しました。これらのキー
が正常に機能しなかった可能性があります。クライアントが新しく接続されたときに削除されました。ディスク上の対応するフォルダが削除されました。ここでメモリリークが発生したことを確認できます。
詳細な分析
まず第一に、見つけることは難しくありません
- MAPはプライベートオブジェクトであるため、MAPに対する操作は通常AbstractManagerを介して行われます。
- MAPは静的であり、同様のオブジェクト間で共有されます
- MAP参照は不変であり、MAPの作成と置換のそのような操作はありません
ただし、removeのベースとなるAbstractManagerの名前はプライベートです。つまり、複数のAbstractManager実装クラスがMAPを共有し、それらのrelease()メソッドが呼び出されると、それらは独自の名前に従ってMAPから削除されます。
前の記事の分析から、MAPの多くのキーは削除されていませんが、これらのAbstractManagerのrelease()メソッドが呼び出されていないことを意味しますか?
この考え方に従って、AbstractOutputStreamAppender.stop()が呼び出されると、this.manager.release()が呼び出されます。
そのマネージャーもプライベートであり、他のオブジェクトがこれを操作することはなく、リリースは再度停止されたときにのみ発生します。
AbstractOutputStreamAppenderの実装クラスが正しく停止されている場合、マネージャーも正しくreleased()されている必要があり、MAPにはそれほど多くのキーがありませんが、逆のことが当てはまります。つまり、AbstractOutputStreamAppenderとAbstractManagerの実装クラスの合計にはまた、リークされました。
メソッドスタックを深く掘り下げると、特定の実装クラスがわかります。
このクラスのオブジェクトを見ると、多くの実装クラスがあり
、前の接続から残しておく必要があることがわかります。この実装クラスは静的に呼び出されます。LogUtilsによるものであり、LogUtilsのリークがないはずです。次に、メソッドスタックを見ると、LogUtilsがクエリを停止するアペンダーであることがわかります。これは、以前にクエリされたキーを削除できる理由も説明できます。
現在、接続の最後にアペンダーを見つけて正しく停止する限り、この問題は解決できます。
多くのブレークポイントデバッグ部分を省略し、cleanupSessionLogDirメソッドを見つけました
修正してみてください
HiveSessionImplのcleanupSessionLogDir()でこれらのオブジェクトをStop()して、ファイルが役に立たなくなったときにファイルがstopped()であることを確認できるようにします。
sessionLogDir.list()はこれらのファイル名を取得できます
以前の分析では、LogUtils.stopQueryAppender(LogDivertAppender.QUERY_ROUTING_APPENDER、queryId)がこれらを閉じることができることがわかりました
//stopQueryAppender
String[] queryIdArr = sessionLogDir.list();
for(String queryId:queryIdArr) {
LogUtils.stopQueryAppender(LogDivertAppender.QUERY_ROUTING_APPENDER, queryId);
}
コンパイルのために送信し、リリースしてオンラインにし、再テストし、初めて接続し、問題が発生した場所MAP.remove(this.name)にクエリを開始すると、マップに27 kvがあり、30kvしかないことがわかりました。が再び接続され、このセッションのみがあります。Kv
が再度テストされ、MAPにはまだ30 kvしかありません
が、RandomAccessFileAppenderにはまだ78があり、3つのセッションは27、26、および25です
。GCをトリガーしない可能性があり、その後消えます。 GC。つまり、少なくともMAPリークの問題は解決されました。