适用于4GB JVM和3GB缓存的JVM / GC调优

时间:2022-04-16 14:33:50

I am looking for the appropriate settings to configure the JVM for a web application. I have read about old/young/perm generation, but I have trouble using those parameters at best for this configuration.

我正在寻找适当的设置来配置Web应用程序的JVM。我已经读过关于old / young / perm生成的内容,但是我最好在这个配置中使用这些参数。

Out of the 4 GB, around 3 GB are used for a cache (applicative cache using EhCache), so I'm looking for the best set up considering that. FYI, the cache is static during the lifetime of the application (loaded from disk, never expires), but heavily used.

在4 GB中,大约3 GB用于缓存(使用EhCache的应用缓存),因此我正在寻找最佳设置。仅供参考,缓存在应用程序的生命周期内是静态的(从磁盘加载,永不过期),但使用频繁。

I have profiled my application already, and I have performed optimization regarding the DB queries, the application's architecture, the cache size, etc... I am just looking for JVM configuration advices here. I have measured 99% throughput for the Garbage Collector, and 6-8s pauses when the Full GC runs (approximately once every 1/2h).

我已经分析了我的应用程序,并且我已经对数据库查询,应用程序的体系结构,缓存大小等进行了优化......我只是在这里寻找JVM配置建议。我已经测量了垃圾收集器的99%吞吐量,并且当Full GC运行时大约6-8s暂停(大约每1 / 2h一次)。

Here are the current JVM parameters:

以下是当前的JVM参数:

-XX:+UseParallelGC -XX:+AggressiveHeap -Xms2048m -Xmx4096m
-XX:NewSize=64m -XX:PermSize=64m -XX:MaxPermSize=512m
-verbose:gc -XX:+PrintGCDetails -Xloggc:gc.log

Those parameters may be completely off because they have been written a long time ago... Before the application became that big.

这些参数可能完全关闭,因为它们很久以前就被写过了......在应用程序变得那么大之前。

I am using Java 1.5 64 bits.

我使用Java 1.5 64位。

Do you see any possible improvements?

你看到任何可能的改进吗?

Edit: the machine has 4 cores.

编辑:机器有4个核心。

3 个解决方案

#1


5  

-XX:+UseParallel*Old*GC should speed up the Full GCs on a multi core machine.

-XX:+ UseParallel * Old * GC应该可以加速多核机器上的Full GC。

You could also profile with different NewRatio values. Your cached objects will live in the tenured generation so profile it with -XX:NewRatio=7 and then again with some higher and lower values.

您还可以使用不同的NewRatio值进行分析。您的缓存对象将存在于tenured generation中,因此使用-XX:NewRatio = 7对其进行分析,然后再使用一些更高和更低的值进行分析。

You may not be able to accurately replicate realistic use during profiling, so make sure you monitor GC when it is in real life use and then you can make minor changes (e.g. to survivor space etc) and see what effect they have.

您可能无法在分析过程中准确复制实际使用,因此请确保在实际使用中监视GC,然后您可以进行微小更改(例如幸存者空间等)并查看它们具有的效果。

Old advice was not to use AggressiveHeap with Xms and Xmx, I am not sure if that is still true.

老建议不是将AggressiveHeap与Xms和Xmx一起使用,我不确定是否仍然如此。

Edit: Please let us know which OS/hardware platform you are deployed on.

编辑:请告诉我们您部署的操作系统/硬件平台。

Full collections every 30 mins indicates the old generation is quite full. A high value for newRatio will give it more space at the expense of the young gen. Can you give the JVM more than 4g or are you limited to that?

每30分钟收集一次,表明老一代人已经满员。 newRatio的高价值将为年轻人带来更多空间。你能给JVM超过4克还是仅限于此?

It would also be useful to know what your goals / non functional requirements are. Do you want to avoid these 6 / 7 second pauses at the risk of lower throughput or are those pauses an acceptable compromise for highest possible throughput?

知道您的目标/非功能要求是什么也是有用的。您是否希望避免这些6/7秒暂停以降低吞吐量的风险,或者是否为可能的最高吞吐量暂停可接受的折衷?

If you want to minimise the pauses, try the CMS collector by removing both

如果要最小化暂停,请通过删除两者来尝试CMS收集器

-XX:+UseParallelGC -XX:+UseParallelOldGC 

and adding

-XX:+UseConcMarkSweepGC -XX:+UseParNewGC

Profile with that with various NewRatio values and see how you get on.

使用各种NewRatio值的配置文件,看看你如何继续。

One downside of the CMS collector is that unlike the parallel old and serial collectors, it doesn't compact the old generation. If the old generation gets too fragmented and a minor collection needs to promote a lot of objects to the old gen at once, a full serial collection may be invoked which could mean a long pause. (I've seen this once in prod but with the IBM JVM which went out of memory instead of invoking a compacting collection!)

CMS收集器的一个缺点是,与并行的旧的和串行的收集器不同,它不会压缩老一代。如果旧代变得过于分散并且次要集合需要同时向旧版本推广大量对象,则可能会调用完整的序列集合,这可能意味着长时间停顿。 (我曾经在prod中看过这个,但是IBM JVM的内存不再是调用压缩集合!)

This might not be a problem for you - it depends on the nature of the application - but you can insure against it by restarting nightly or weekly.

这对您来说可能不是问题 - 这取决于应用程序的性质 - 但您可以通过每晚或每周重新启动来保证它。

#2


4  

I would use Java 6 update 30 or 7 update 2, 64-bit as they are much more efficient. e.g. they use 32-bit references by default.

我会使用Java 6更新30或7更新2,64位,因为它们更有效。例如它们默认使用32位引用。

I would also configure Ehcache to use direct memory or a memory mapped file if possible. This should minimise the impact on GC.

如果可能的话,我还会将Ehcache配置为使用直接内存或内存映射文件。这应该最小化对GC的影响。

Using these options its possible to almost eliminate your heap foot print. e.g. I have an app which uses up to 180 GB of memory mapped files on a machine with 16 GB of memory and the heap size is 6 MB. A full GC takes up to 11 ms when trigger manually, not that it ever GCs. ;)

使用这些选项可以几乎消除堆脚印。例如我有一个应用程序,在具有16 GB内存的计算机上使用高达180 GB的内存映射文件,堆大小为6 MB。手动触发时,完整GC最多需要11 ms,而不是GC。 ;)

If you want a simple example where I map in an 8 TB file into memory and update it. http://vanillajava.blogspot.com/2011/12/using-memory-mapped-file-for-huge.html

如果你想要一个简单的例子,我将8 TB文件映射到内存并更新它。 http://vanillajava.blogspot.com/2011/12/using-memory-mapped-file-for-huge.html

#3


0  

I hope you just removed -server to not inflate the post, otherwise you should instantly enable it. Apart from the bit longer startup time (which really isn't an issue for a web application that should run days) I don't see any reason to use anything but c2. That could give some nice performance improvements in general. Umn back to topic:

我希望你刚删除-server不要给帖子充气,否则你应该立即启用它。除了更长的启动时间(对于应该运行几天的Web应用程序来说,这确实不是问题)我没有看到任何理由除了使用c2之外的任何东西。总的来说,这可以带来一些不错的性能提升。 Umn回到主题:

Sadly the best thing I can think of won't work with your ancient JVM. The G1 garbage collector was basically designed to reduce latency. Not only does it try to reduce pauses in general, it also offers some tuning parameters to set pause goals and intervals. See this page.

可悲的是,我能想到的最好的东西不适用于您的古*VM。 G1垃圾收集器基本上是为减少延迟而设计的。它不仅试图减少暂停,还提供一些调整参数来设置暂停目标和间隔。见本页。

There is an experimental backport to java6 though I doubt it's kept up to date. And nobody is wasting any time on optimizing GC or anything else for Java 1.5 anymore I fear.

有一个实验性的反向java6虽然我怀疑它是保持最新的。没有人浪费任何时间来优化GC或Java 1.5的任何其他事情我担心。

PS: There would also be IBM's JVM and obviously azul systems (ok that wasn't a serious proposition ;) ), but those are obviously out of the question.. just wanted to mention them.

PS:还有IBM的JVM和明显的azul系统(确定这不是一个严肃的命题;)),但这些显然是不可能的......只是想提及它们。

#1


5  

-XX:+UseParallel*Old*GC should speed up the Full GCs on a multi core machine.

-XX:+ UseParallel * Old * GC应该可以加速多核机器上的Full GC。

You could also profile with different NewRatio values. Your cached objects will live in the tenured generation so profile it with -XX:NewRatio=7 and then again with some higher and lower values.

您还可以使用不同的NewRatio值进行分析。您的缓存对象将存在于tenured generation中,因此使用-XX:NewRatio = 7对其进行分析,然后再使用一些更高和更低的值进行分析。

You may not be able to accurately replicate realistic use during profiling, so make sure you monitor GC when it is in real life use and then you can make minor changes (e.g. to survivor space etc) and see what effect they have.

您可能无法在分析过程中准确复制实际使用,因此请确保在实际使用中监视GC,然后您可以进行微小更改(例如幸存者空间等)并查看它们具有的效果。

Old advice was not to use AggressiveHeap with Xms and Xmx, I am not sure if that is still true.

老建议不是将AggressiveHeap与Xms和Xmx一起使用,我不确定是否仍然如此。

Edit: Please let us know which OS/hardware platform you are deployed on.

编辑:请告诉我们您部署的操作系统/硬件平台。

Full collections every 30 mins indicates the old generation is quite full. A high value for newRatio will give it more space at the expense of the young gen. Can you give the JVM more than 4g or are you limited to that?

每30分钟收集一次,表明老一代人已经满员。 newRatio的高价值将为年轻人带来更多空间。你能给JVM超过4克还是仅限于此?

It would also be useful to know what your goals / non functional requirements are. Do you want to avoid these 6 / 7 second pauses at the risk of lower throughput or are those pauses an acceptable compromise for highest possible throughput?

知道您的目标/非功能要求是什么也是有用的。您是否希望避免这些6/7秒暂停以降低吞吐量的风险,或者是否为可能的最高吞吐量暂停可接受的折衷?

If you want to minimise the pauses, try the CMS collector by removing both

如果要最小化暂停,请通过删除两者来尝试CMS收集器

-XX:+UseParallelGC -XX:+UseParallelOldGC 

and adding

-XX:+UseConcMarkSweepGC -XX:+UseParNewGC

Profile with that with various NewRatio values and see how you get on.

使用各种NewRatio值的配置文件,看看你如何继续。

One downside of the CMS collector is that unlike the parallel old and serial collectors, it doesn't compact the old generation. If the old generation gets too fragmented and a minor collection needs to promote a lot of objects to the old gen at once, a full serial collection may be invoked which could mean a long pause. (I've seen this once in prod but with the IBM JVM which went out of memory instead of invoking a compacting collection!)

CMS收集器的一个缺点是,与并行的旧的和串行的收集器不同,它不会压缩老一代。如果旧代变得过于分散并且次要集合需要同时向旧版本推广大量对象,则可能会调用完整的序列集合,这可能意味着长时间停顿。 (我曾经在prod中看过这个,但是IBM JVM的内存不再是调用压缩集合!)

This might not be a problem for you - it depends on the nature of the application - but you can insure against it by restarting nightly or weekly.

这对您来说可能不是问题 - 这取决于应用程序的性质 - 但您可以通过每晚或每周重新启动来保证它。

#2


4  

I would use Java 6 update 30 or 7 update 2, 64-bit as they are much more efficient. e.g. they use 32-bit references by default.

我会使用Java 6更新30或7更新2,64位,因为它们更有效。例如它们默认使用32位引用。

I would also configure Ehcache to use direct memory or a memory mapped file if possible. This should minimise the impact on GC.

如果可能的话,我还会将Ehcache配置为使用直接内存或内存映射文件。这应该最小化对GC的影响。

Using these options its possible to almost eliminate your heap foot print. e.g. I have an app which uses up to 180 GB of memory mapped files on a machine with 16 GB of memory and the heap size is 6 MB. A full GC takes up to 11 ms when trigger manually, not that it ever GCs. ;)

使用这些选项可以几乎消除堆脚印。例如我有一个应用程序,在具有16 GB内存的计算机上使用高达180 GB的内存映射文件,堆大小为6 MB。手动触发时,完整GC最多需要11 ms,而不是GC。 ;)

If you want a simple example where I map in an 8 TB file into memory and update it. http://vanillajava.blogspot.com/2011/12/using-memory-mapped-file-for-huge.html

如果你想要一个简单的例子,我将8 TB文件映射到内存并更新它。 http://vanillajava.blogspot.com/2011/12/using-memory-mapped-file-for-huge.html

#3


0  

I hope you just removed -server to not inflate the post, otherwise you should instantly enable it. Apart from the bit longer startup time (which really isn't an issue for a web application that should run days) I don't see any reason to use anything but c2. That could give some nice performance improvements in general. Umn back to topic:

我希望你刚删除-server不要给帖子充气,否则你应该立即启用它。除了更长的启动时间(对于应该运行几天的Web应用程序来说,这确实不是问题)我没有看到任何理由除了使用c2之外的任何东西。总的来说,这可以带来一些不错的性能提升。 Umn回到主题:

Sadly the best thing I can think of won't work with your ancient JVM. The G1 garbage collector was basically designed to reduce latency. Not only does it try to reduce pauses in general, it also offers some tuning parameters to set pause goals and intervals. See this page.

可悲的是,我能想到的最好的东西不适用于您的古*VM。 G1垃圾收集器基本上是为减少延迟而设计的。它不仅试图减少暂停,还提供一些调整参数来设置暂停目标和间隔。见本页。

There is an experimental backport to java6 though I doubt it's kept up to date. And nobody is wasting any time on optimizing GC or anything else for Java 1.5 anymore I fear.

有一个实验性的反向java6虽然我怀疑它是保持最新的。没有人浪费任何时间来优化GC或Java 1.5的任何其他事情我担心。

PS: There would also be IBM's JVM and obviously azul systems (ok that wasn't a serious proposition ;) ), but those are obviously out of the question.. just wanted to mention them.

PS:还有IBM的JVM和明显的azul系统(确定这不是一个严肃的命题;)),但这些显然是不可能的......只是想提及它们。