2012-11-01 21 views
17

Tôi đã chuyển sang SDK Java của Máy ứng dụng Google 1.7.3 gần đây. Kể từ đó, tôi đang hết không gian PermGen mỗi khi tôi gửi DeferredTasks vào hàng đợi công việc.Chạy ra khỏi không gian PermGen khi sử dụng DeferredTasks trong GAE 1.7.3

  • Điều này không xảy ra khi ứng dụng được triển khai vào App Engine. Nó chỉ xảy ra cục bộ. Nhưng nó đang chặn thử nghiệm địa phương của tôi và thử nghiệm tích hợp không thành công.
  • Nó đang xảy ra trên MacOSX 10.7.5 với 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) 
    
  • Và đây là một phần của stacktrace tôi nhìn thấy khi vấn đề xảy ra.

    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 
    

Xem dưới đây để biết mã kích hoạt vấn đề này. DeferredTask có tham chiếu memcache để lấy dữ liệu từ memcache và có khả năng xóa nó. Nhiệm vụ đang chạy với thời gian trễ là 10 giây.

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

Người khác có thể tạo lại điều này không? Cảm ơn!

Cập nhật: Tôi đã tạo issue 8377 cho điều này trên trang Google Code của GAE.

+4

Tại sao bạn không tăng dung lượng bộ nhớ bằng XXMaxPermSize JVM arg? –

+2

Trước hết, tôi nghĩ rằng có điều gì đó không ổn trong ứng dụng của tôi/GAE. ** Tôi không làm gì đặc biệt và muốn hiểu lý do tại sao tôi đang chạy ra khỏi không gian PermGen. Tôi thực sự bắt đầu GAE và gọi một URL có thêm DeferredTask. ** Thứ hai, tôi đang sử dụng maven-gae-plugin. Và cả hai (1) thêm XXMaxPermSize vào ** MAVEN_OPTS ** và (2) thêm nó vào .. của maven-gae-plugin không thay đổi kích thước của không gian PermGen. Việc này không được JVM bắt đầu bởi Maven để chạy GAE. – Ingo

+1

Làm cách nào để tăng khoảng trống PermGen khi chạy trong GAE? Điều đó thậm chí có thể? – Ingo

Trả lời

2

Vấn đề này đã được giải quyết ngày 12 tháng 8 năm 2014 trong bản phát hành SDK AppEngine 1.9.6. MaxPermSize chỉ có thể được đặt trên máy chủ dev cục bộ.

+0

MaxPermSize chỉ có thể được đặt trên máy chủ dev cục bộ. , làm sao? –

Các vấn đề liên quan