2012-11-01 22 views
17

最近,我切换到Google App Engine Java SDK 1.7.3。从那以后,我每次将DeferredTasks提交到任务队列中时,我都用完了PermGen空间在GAE中使用DeferredTasks时耗尽了PermGen空间1.7.3

  • 当应用程序部署到App Engine时不会发生这种情况。它只发生在本地。但是它阻止了我的本地测试和失败的集成测试。
  • 据MacOSX上10.7.5发生与Java 6

    $ java -version 
    java version "1.6.0_37" 
    Java(TM) SE Runtime Environment (build 1.6.0_37-b06-434-11M3909) 
    Java HotSpot(TM) 64-Bit Server VM (build 20.12-b01-434, mixed mode) 
    
  • 这是堆栈跟踪出现问题时,我看到的一部分。

    INFO: Successfully processed ../target/projectName/WEB-INF/queue.xml 
    Nov 1, 2012 3:04:00 PM com.google.appengine.api.taskqueue.dev.LocalTaskQueue init 
    INFO: LocalTaskQueue is initialized 
    Nov 1, 2012 3:04:01 PM org.quartz.simpl.SimpleThreadPool initialize 
    INFO: Job execution threads will use class loader of thread: [email protected] 
    Nov 1, 2012 3:04:02 PM org.quartz.core.QuartzScheduler <init> 
    INFO: Quartz Scheduler v.UNKNOWN.UNKNOWN.UNKNOWN created. 
    Nov 1, 2012 3:04:02 PM org.quartz.simpl.RAMJobStore initialize 
    INFO: RAMJobStore initialized. 
    Nov 1, 2012 3:04:02 PM org.quartz.impl.StdSchedulerFactory instantiate 
    INFO: Quartz scheduler 'DefaultQuartzScheduler' initialized from default resource file in Quartz package: 'quartz.properties' 
    Nov 1, 2012 3:04:02 PM org.quartz.impl.StdSchedulerFactory instantiate 
    INFO: Quartz scheduler version: UNKNOWN.UNKNOWN.UNKNOWN 
    Nov 1, 2012 3:04:02 PM org.quartz.core.QuartzScheduler start 
    INFO: Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started. 
    Nov 1, 2012 3:04:02 PM com.google.appengine.api.taskqueue.dev.LocalTaskQueue start_ 
    INFO: Local task queue initialized with base url http://localhost:8083 
    Exception in thread "DefaultQuartzScheduler_Worker-9" java.lang.OutOfMemoryError: PermGen space 
         at java.lang.ClassLoader.defineClass1(Native Method) 
         at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631) 
         at java.lang.ClassLoader.defineClass(ClassLoader.java:615) 
         at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141) 
         at java.net.URLClassLoader.defineClass(URLClassLoader.java:283) 
         at java.net.URLClassLoader.access$000(URLClassLoader.java:58) 
         at java.net.URLClassLoader$1.run(URLClassLoader.java:197) 
         at java.security.AccessController.doPrivileged(Native Method) 
         at java.net.URLClassLoader.findClass(URLClassLoader.java:190) 
         at java.lang.ClassLoader.loadClass(ClassLoader.java:306) 
         at com.google.appengine.tools.development.DevAppServerClassLoader.loadClass(DevAppServerClassLoader.java:92) 
         at java.lang.ClassLoader.loadClass(ClassLoader.java:247) 
         at com.google.appengine.api.urlfetch.URLFetchServicePb$URLFetchRequest.newBuilder(URLFetchServicePb.java:1902) 
         at com.google.appengine.api.taskqueue.dev.UrlFetchJob.newFetchRequest(UrlFetchJob.java:152) 
         at com.google.appengine.api.taskqueue.dev.UrlFetchJob.execute(UrlFetchJob.java:83) 
         at org.quartz.core.JobRunShell.run(JobRunShell.java:203) 
         at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:520) 
    Exception in thread "[email protected]" java.lang.OutOfMemoryError: PermGen space 
    Exception in thread "Timer-6" java.lang.OutOfMemoryError: PermGen space 
    Exception in thread "Timer-4" java.lang.OutOfMemoryError: PermGen space 
    Exception in thread "Timer-2" java.lang.OutOfMemoryError: PermGen space 
    Exception in thread "Timer-8" java.lang.OutOfMemoryError: PermGen space 
    

的触发问题的代码,请参阅下文。 DeferredTask有一个memcache引用来从memcache获取数据并可能删除它。该任务延迟10秒运行。

class Foo { 
    private void enqueueTask() { 
     queue.add(TaskOptions.Builder.withPayload(new Task()).countdownMillis(10 * 1000)); 
    } 

    private static class Task implements DeferredTask { 
     private static final MemcacheService memcache = MemcacheServiceFactory.getMemcacheService(); 
     private static final Logger log = Logger.getLogger(Task.class.getName()); 

     @Override 
     public void run() { 
      final String key = ...; 

      if (memcache.contains(key)) { 
       final Object value = memcache.get(key); 

       if (some condition depending on value) { 
        memcache.delete(key); 
        memcache.increment(some other field, -1l); 
       } 
      } else { 
       log.warning("error message"); 
      } 
     } 
    } 
} 

其他人可以重现吗?谢谢!

更新:我在GAE的Google代码页上为此创建了issue 8377

+4

为什么不使用XXMaxPermSize JVM arg增加一定量的内存? –

+2

首先,我认为我的应用程序/ GAE本身出了问题。 **我没有做任何特别的事情,并想了解为什么我的PermGen空间用完了。我从字面上开始GAE并调用一个URL添加一个DeferredTask。** 其次,我使用maven-gae-plugin。并且(1)将XXMaxPermSize添加到** MAVEN_OPTS **和(2)将它添加到maven-gae-plugin的 ..不会更改PermGen空间的大小。 Maven启动的运行GAE的JVM并没有找到这一点。 – Ingo

+1

如何在GAE中运行时增加PermGen空间?这甚至有可能吗? – Ingo

回答

2

2014年8月12日在1.9.6 AppEngine SDK版本中解决了此问题。 只能在本地开发服务器上设置MaxPermSize。

+0

MaxPermSize只能在本地开发服务器上进行设置。 , 怎么样? –