Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running out of PermGen space when using DeferredTasks in GAE 1.7.3

I switched to Google App Engine Java SDK 1.7.3 recently. Since then, I am running out of PermGen space every time I am submitting DeferredTasks into the task queue.

  • This does not happen when the app is deployed to App Engine. It only happens locally. But it is blocking my local testing and failing integration tests.
  • It is happening on MacOSX 10.7.5 with 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)
    
  • And this is part of stacktrace I am seeing when the problem occurs.

    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: 1255545583@qtp-1458850232-0
    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 "1255545583@qtp-1458850232-0" 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
    

See below for the code that triggers the issue. The DeferredTask has a memcache reference to get data from memcache and potentially remove it. The task is running with a delay of 10 seconds.

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");
            }
        }
    }
}

Can somebody else reproduce this? Thanks!

Update: I created issue 8377 for this on the GAE's Google Code page.

like image 669
Ingo Avatar asked Nov 01 '12 20:11

Ingo


People also ask

How do you fix a PermGen error?

To fix it, increase the PermGen memory settings by using the following Java VM options. -XX:PermSize<size> - Set initial PermGen Size. -XX:MaxPermSize<size> - Set the maximum PermGen Size. In the next step, we will show you how to set the VM options in Tomcat, under Windows and Linux environment.

How can I increase my PermGen size?

To increase PermGen, we have the following commands: -XX:PermSize=N - sets the initial (and minimum size) of the Permanent Generation space. -XX:MaxPermSize=N - sets the maximum size of the Permanent Generation space.

What causes PermGen space error?

lang. OutOfMemoryError: PermGen Space is a runtime error in Java which occurs when the permanent generation (PermGen) area in memory is exhausted. The PermGen area of the Java heap is used to store metadata such as class declarations, methods and object arrays.

How do I increase PermGen space in Weblogic?

To set PermGen size you can use e.g. -XX:PermSize=512m -XX:MaxPermSize=512m . Regarding Weblogic, set the JAVA_OPTIONS and see if these options are properly passed in as parameters into your Java process. You can also directly set these parameters in the startWeblogic.


1 Answers

This isssue was resolved Aug 12, 2014 in the 1.9.6 AppEngine SDK release. MaxPermSize can only be set on the local dev server.

like image 96
Bogdan.Nourescu Avatar answered Nov 14 '22 04:11

Bogdan.Nourescu