【问题标题】:How to set max Permgen settings in production Google App Engine server如何在生产 Google App Engine 服务器中设置最大 Permgen 设置
【发布时间】:2015-11-17 03:09:30
【问题描述】:

我正在使用默认 F1 服务器实例的自动缩放在 google 应用引擎上运行一个 Web 模块。昨天,我注意到生产中出现 PermGen,Out of Memory 服务器异常。这让我很担心,因为当这个错误发生在他们的网络请求响应时,我的用户会收到一个空白屏幕,这会引起很多混乱。此外,我的应用处于试验阶段,只有几个用户并且没有负载,因此要接收 permgen,OutOfMemory 服务器异常意味着随着事情的发展,可能会有更多。

有没有办法增加谷歌应用引擎配置上的最大 PermGen 内存分配?我已经搜索并没有找到有关更改生产应用程序引擎服务器(仅开发服务器,我已经成功完成)上的设置的任何内容。如果我将正在使用的服务器更改为具有更多内存的服务器(例如 F2 服务器实例),会有帮助吗?我假设即使是更高内存的服务器实例仍将使用默认的 max permGen 设置,所以我不这么认为。

感谢您告诉我如何减少在生产谷歌应用引擎服务器中收到这些 OutOfMemory 错误的可能性。

这是错误的堆栈跟踪

java.lang.OutOfMemoryError: PermGen space at sun.misc.Unsafe.defineClass(Native Method) 在 sun.reflect.ClassDefiner.defineClass(ClassDefiner.java:63) 在 sun.reflect.MethodAccessorGenerator$1.run(MethodAccessorGenerator.java:399) 在 sun.reflect.MethodAccessorGenerator$1.run(MethodAccessorGenerator.java:396) 在 java.security.AccessController.doPrivileged(Native Method) 在 sun.reflect.MethodAccessorGenerator.generate(MethodAccessorGenerator.java:395) 在 sun.reflect.MethodAccessorGenerator.generateMethod(MethodAccessorGenerator.java:77) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:46) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:606) 在 java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1017) 在 java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2040) 在 java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1936) 在 java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1462) 在 java.io.ObjectInputStream.readObject(ObjectInputStream.java:417) 在 java.util.HashMap.readObject(HashMap.java:1182) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:606) 在 java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1017) 在 java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2040) 在 java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1936) 在 java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1462) 在 java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2140) 在 java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2064) 在 java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1936) 在 java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1462) 在 java.io.ObjectInputStream.readObject(ObjectInputStream.java:417) 在 com.google.apphosting.runtime.SessionManagerUtil.deserialize(SessionManagerUtil.java:56) 在 com.google.apphosting.runtime.MemcacheSessionStore.getSession(MemcacheSessionStore.java:38) 在 com.google.apphosting.runtime.jetty.SessionManager.loadSession(SessionManager.java:330)

【问题讨论】:

  • 我认为如果没有托管 VM,您将无法更改 PermGen 内存。更改 PermGen 意味着应用引擎中的整个扩展机制必须进行调整,因为可以在单个 VM 上运行更少的实例。因此,显而易见的选择是现在允许它。看起来您的会话中有大量数据,或者至少这是异常的来源。然而,内存缓存被限制为 1 MB,所以我假设导致这种情况的内存消耗发生在其他地方。
  • 感谢您的洞察力。作为第一次尝试,我将尝试减少我的用户会话占用空间。应用引擎文档有一些关于如何将会话数据持久保存到数据存储的内容,并且它还使用内存缓存来提高速度。 google docs。如果这没有帮助,我可能需要按照您的建议使用托管 VM,如果这允许我调整 permgen 设置。
  • @KurtHartmann 如果我遇到你的情况,我会直接跳到 MVM,因为有了它,你肯定可以轻松地调整你想要的东西。减少用户会话并不一定容易,如果你最终减少的不够多,你会遇到同样的限制。我必须指出,尽管 MVM 仍处于测试阶段,因此您应该小心运行任何对它的批评。
  • @Patrice 托管 VM 托管对我来说听起来像是一个很好的长期解决方案。知道它何时退出 beta 测试吗?我的应用距离正式发布还有 3 个月的时间。到那时,托管 VM 会稳定并准备好生产吗?
  • @KurtHartmann 我很乐意为您提供这方面的信息,但很遗憾我没有确切的日期

标签: google-app-engine out-of-memory


【解决方案1】:

对托管应用程序的实例进行更多控制的唯一方法是使用Managed VMs

虽然在这种情况下最小化用户会话可能会有所帮助,但这并不总是容易且不能保证(因为您可以最小化但仍会达到限制)。

小心使用托管虚拟机(记住它们的扩展方式也不同,因此请务必阅读this,尤其是扩展部分),因为它们仍处于测试阶段,这意味着它们不应该在生产环境中使用关键应用程序。

【讨论】:

    猜你喜欢
    • 2012-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-23
    • 1970-01-01
    • 1970-01-01
    • 2013-11-24
    • 2019-08-12
    相关资源
    最近更新 更多