2010-09-29 59 views
36

是否可以在Sun JVM中執行垃圾收集器日誌的滾動?在java中滾動垃圾收集器日誌

目前我生成日誌使用:

-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -verbose:gc -Xloggc:gc.log 

但我不得不使用FIFO隊列和rotatelogs創造每一天的新日誌手動旋轉它們。我希望有更好的解決方案。

也許有辦法從java內部訪問這個日誌條目,所以我可以將它們重定向到log4j?

編輯:與FIFO隊列的解決方案是不夠的,因爲如果從這個隊列中讀取的過程中(如rotatelogs)讀取慢會拖慢整個JVM(顯然太陽/ Oracle 10g中,GC日誌同步)

+0

您的解決方案對我來說聽起來很不錯;你不喜歡它什麼?您有託管:輪換髮生在您的Java調用(它配置日誌記錄)附近,而不是在應用程序代碼中(應該忘記日誌記錄)。 – 2010-09-29 13:49:52

+0

另外我的直覺會說不,不可能,或者如果可能的話,它會通過一個私人的,有限的API,你可能不想強制進入你的應用程序。 – 2010-09-29 13:52:28

+0

-XX:+ PrintGCDateStamps不適用於java5? – 2011-02-23 21:54:52

回答

77

GC日誌旋轉的內置支持已添加到HotSpot JVM中。 它在RFE 6941923描述,並提供:

有三個新的JVM標誌可用於啓用和配置它:

  • -XX:+UseGCLogFileRotation
    必須與-Xloggc:<filename>一起使用;
  • -XX:NumberOfGCLogFiles=<number of files>
    必須> = 1,默認值爲1;
  • -XX:GCLogFileSize=<number>M (or K)
    默認值將被設置爲512K。
+5

-XX:NumberOfGClogFiles應該有一個大寫字母L(-XX:NumberOfGCLogFiles) – 2013-03-22 13:17:12

+0

很可惜,這不是每天,我沒有看到一個大小滾動的點,我通常會看到從給定日期的日誌,而不是123MB :) – 2016-07-04 19:51:45

+2

大小滾動的關鍵在於日誌文件的總大小受到限制(NumberOfGCLogFiles * GCLogFileSize),它避免了無空間的設備錯誤,並且超過了查找給定日期的日誌的不便之處。 – vboerchers 2016-08-04 13:04:50

3

你試過這個新選項嗎?

我試過jdk7u7,jdk7u6和jdk6u35這樣的:

java -Xloggc:gc.log -XX:+PrintGCDetails -XX:+UseGCLogRotation -XX:NumberOfGClogFiles=3 -XX:GCLogFileSize=10M 

但每一個版本我看到這個錯誤:

Error: Could not create the Java Virtual Machine. 
Error: A fatal exception has occurred. Program will exit. 

修正錯誤#6941923爲7U2此處引用:http://www.oracle.com/technetwork/java/javase/2col/7u2bugfixes-1394661.html

+1

你的標誌是錯誤的 - 這是「-XX:+ UseGCLogFileRotation」(你缺少的標誌「文件」) – Ryan 2013-05-13 15:55:27

+1

和資本「L」中缺少「-XX:NumberOfGClogFiles」(因爲它本來是我的答案) – 2013-05-30 08:31:21

+0

這不是Blazej的錯,錯別字在他引用的bug文檔中(http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6941923)。 – t0r0X 2016-01-25 20:06:51

5

如果您無法升級您的Java版本以使用新標誌來旋轉gc日誌,那麼您可以在每次應用程序啓動時指定一個不同的gc文件s:

JAVA_OPTS="-Xms1024m -Xmx1024m -XX:MaxPermSize=256m -verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:/path/to/log/dir/gc.log-"`date +%Y-%m-%d-%H-%M` 

當setenv被引用時,通常在啓動或關閉時,它會引用另一個日誌文件。在unix中,這可以用作'旋轉'日誌的方法。

+0

更好的方法是將詳細輸出附加到文件,並使用logrotate或類似文件旋轉此文件。你會得到更長的日誌,而不會分解成各種不同的文件。 – 2013-09-27 23:36:02

+2

@Pathduck這個答案適用於較老的Java版本。這意味着你不能附加到Xlogcc。我的實驗還表明,您不能導致正在運行的java關閉並重新打開日誌。你也不能讓它尋找(EOF),java會記住Xloggc中的文件位置。主要PITA。 – kubanczyk 2015-04-01 14:10:55

+0

@Pathduck不幸的是,並非所有的系統都有logrotate。這個解決方案發布給管理員,他們不得不這樣做。以這種方式追加日期也是有用的catalina.out的:-) – Underverse 2015-04-11 09:16:30

1

一個有趣的方法是重定向gc。記錄到一個命名管道 -Xloggc:/my/named/pipe How to write GC log to named pipe

然後讀取該管道形成應用程序本身: How to open a Windows named pipe from Java?

並登錄到任意(例如異步軋製)的logback記錄器從代碼。

在Windows機器上試過。不幸的是,在Windows上安裝比在Linux上更麻煩。

在Windows上,它基本上在另外的Powershell script(也可以是專用應用程序)的幫助下工作。 此sample project還包含一個演示應用程序,可以立即使用它來測試GC日誌通過SLF4J重定向到Logback。

+0

根據我的理解,您必須讓一位消費者傾聽命名管道,否則它最終會阻塞。 – 2016-09-01 12:30:19

+0

是的,這就是腳本項目。它還包含一個「閥門」,沒有任何東西可以接收到這些信息,還有一些評論描述了這一點。 – 2016-09-01 19:26:44

+0

儘管它很吸引人,但意味着您的應用程序現在依賴於此外部組件正常運行。這對我們來說很可能意味着我們無法在生產中使用它: -/ – 2016-09-02 08:12:24