2010-07-28 101 views

回答

0

它用于规模最大永久代。在一些算法中,或者如果你使用很多很多很多不同的类,你可以使用它。给this one一读。

但大多数情况下它用作考试问题......

+5

这只是说它是什么,它并不能解释它为什么存在于第一位。 – 2010-07-28 20:15:21

0

它的存在,因为它有助于调整JVM内的垃圾收集子系统。根据底层体系结构和内存管理,JVM实现可能具有次优化的垃圾收集(例如,太多thrashy)...您可以手动指定MaxPermSize,而不是计算它,以便应用程序的行为顺利...

Java GC Page says more...

+4

但为什么最大尺寸在第一位?为什么不让它增长,直到达到操作系统对进程的内存大小限制? – 2010-07-28 20:22:10

+0

@JonathanAllen我之前在基于容器的虚拟化解决方案(OpenVZ)中看到过问题,其中Java或其他进程看到了物理主机的可用内存和/假设/它有足够的可用内存。最终,容器控制器杀死了超过内存限制的进程。 'MaxPermSize'可以帮助解决这种情况,让我告诉虚拟机有多少内存可用。 – BSchlinker 2013-04-29 09:24:13

22

这里是在垃圾收集器的永久代的好文章:

Presenting the Permanent GenerationJon Masamitsu's Weblog

编辑:

我还没有看到任何迹象表明他们为什么要让设计决定对永久代的尺寸有最大限制。但我想这是因为几个原因。

  1. 它使它更容易实现,GC决定不是微不足道的,所以以任何方式简化您的实现可能是一个好主意。 YAGNI(你不会需要它)大多数应用程序加载固定数量的类,通常它不是特别大,所以它们可能已经为常见情况进行了优化,只是选择了一个理智的默认值,并使其可配置。

  2. 假设您的perm gen大小增长到不可预知的大,那么您可能在类加载器中出现错误(或需要重新考虑您的体系结构)。即使在运行时产生类的应用程序(或者其他类似的技巧)中,生成的类的数量也通常是固定的,所以您应该能够调整maxperm以适应您的需求。

  3. 我并不是所有java类加载和垃圾收集细节的专家,但他们都是JVM的复杂部分,所以我想他们会尽量保持这两个组件尽可能正交,并且允许烫发会动态增长可能会以复杂的方式将这两个组件结合在一起(特别是因为这两个组件都有严重的线程考虑因素)

  4. 上限可能会有一些性能上的好处,允许它增长可能涉及额外复制集合,或者这可能意味着您的perm代不再存在于连续的地址空间中,这可能会影响您的其他算法用于管理的方式集合。

显然这些都是猜测。但即使所有这些都是错误的,我绝对不认为太阳选择固定尺寸是'白痴',但可能有更多的工程和实施考虑因素比我甚至可以梦想:)

+4

这并没有说明他们为什么决定给它一个任意的最大尺寸。如果它像其他任何应用程序一样,那么您只需一次为它分配一个空间,直到达到操作系统限制。 – 2010-07-28 20:20:01

+0

除非需要将整个堆预先分配为连续的块,我不相信,否则实际上会通过引入最大大小来增加复杂性。不像一个线程的堆栈,我想不出为什么你需要一个连续的块。 – 2010-07-28 23:55:27

+1

烫发代码的大小与“常规”堆的管理方式不同(链接的文章中提到了这一点),并且事实上它是预先分配的。 – luke 2010-07-29 00:30:41

6

要呈现略有不同的观点,IBM JVM没有permgen,而是出于操作系统的需要分配大量内存。 (传言是jrockit也是如此,但我无法确定)

这样做的好处在于,您不会达到(看似)任意限制,并且需要调整它以适应合理的增长情况。

另一方面,这是一个失控应用程序的问题(本质上是泄漏类) - JVM将基本上去并占用地址空间中的所有内存。这可能会导致不良情况,本地代码会突然失败malloc()调用,或Java以奇怪的方式中断 - 就像无法分配新线程(消耗堆栈的内存)。另一个缺点是它不能提供有关JVM的内存部分消耗量的“成本确定性”。

所以这是一个折衷 - 你想如何在“潜在的不好”情况下失败?

0

永久生成器用于保存虚拟机本身的反射,例如类对象和方法对象。这些反射物体被直接分配到永久世代中,并且其大小与其他世代独立。一般来说,这一代的大小可以忽略,因为默认大小是足够的。但是,加载许多类的程序可能需要更大的永久代。

PermSize是额外单独的堆空间,与用户设置的-Xmx值相同。为永久生成保留的堆部分保存了JVM的所有反射数据。如果您的应用程序动态加载和卸载很多类以优化性能,您应该相应地调整大小。基本上,他堆存储对象,并且perm gen保存关于它内部对象的信息。因此,堆越大,烫发所需要的就越大。

默认情况下,MaxPermSize对于-client为32mb,对于-server为64mb。但是,如果您不设置PermSize和MaxPermSize,则除非需要,否则整个堆不会增加。当你设置PermSize和MaxPermSize时,例如192mb,额外的堆空间将在启动时得到分配,并且将保持分配。

0

也许你想给你的用户选择多少内存你的应用程序将占用,是的操作系统确实有一个限制,并会阻止它,但也许用户希望能够限制它在应用程序设置,以便他们可以在当天晚些时候用该内存执行其他操作,而不会导致应用程序崩溃,因为它是ALREADY占用了该空间,因为它正在使用它而无法释放它。因此,在设置菜单中,您有“我们使用的最大内存量”滑块,并且可以调整它,从而相应地调整MaxPermSize

0

通过MaxPermSize设置您的应用程序将在启动时抛出GC内存不足错误,以免您的应用程序启动并运行并让客户致电,因为系统不工作或者非常迟缓。

假设您的虚拟机上有4GB的存储空间,并且您知道您的应用需要2GB的非永久空间才能达到合同约定的性能指标。如果您的烫发将需要超过2GB,启动应用程序没有意义,因为您无法满足工作说明中列出的性能指标。

最好知道在启动时获取更多内存,或重新配置虚拟机以获取更多物理服务器内存(不管情况如何),而不是启动应用程序,允许类, ehcache或其他任何要加载的内容,都认为一切正常,然后从客户那里了解到系统需要10秒才能加载页面。

+0

不,MaxPermSize确实不会保证你的应用在启动时会失败,如果它加载的类太多。 Java可以(也会)在运行时根据需要加载类,所以限制可能只会在例如某种方法第一次运行,并加载所需的类。 – sleske 2016-04-18 15:34:36