ExecutorService OutOfMemoryError: thread creation failed

最近在ViewPager中定时的平滑滑动函数体里使用了ExecutorService,由线程池执行滑动动作。但不知道怎么的,以下部分抛出了内存溢出错误。但改回原来的每调用一次函数体执行一次new Thread(new Runnable…).start()又感觉虚拟机太忙了。

错误如下:

E/mov_parser_oal: Try to read sample failed!
10-25 15:51:00.675 4141-4141/xx.xx E/dalvikvm: Thread creation failed (err=Invalid argument)
10-25 15:51:00.675 4141-4141/xx.xx D/AndroidRuntime: Shutting down VM
10-25 15:51:00.675 4141-4141/xx.xx W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x414ef930)
10-25 15:51:00.685 4141-4141/xx.xx E/AndroidRuntime: FATAL EXCEPTION: main
                                                                       java.lang.OutOfMemoryError: thread creation failed
                                                                           at java.lang.VMThread.create(Native Method)
                                                                           at java.lang.Thread.start(Thread.java:1050)
                                                                           at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:913)
                                                                           at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1295)
                                                                           at android.support.v4.view.DirectionalViewPager.smoothScrollTo(DirectionalViewPager.java:1317)
                                                                           at android.support.v4.view.DirectionalViewPager.setCurrentItemInternal(DirectionalViewPager.java:1286)
                                                                           at android.support.v4.view.DirectionalViewPager.setCurrentItem(DirectionalViewPager.java:1252)
                                                                           at com.idea_code.business.ad.AdBusinessProcess$1$1.run(AdBusinessProcess.java:97)
                                                                           at android.os.Handler.handleCallback(Handler.java:725)
                                                                           at android.os.Handler.dispatchMessage(Handler.java:92)
                                                                           at android.os.Looper.loop(Looper.java:137)
                                                                           at android.app.ActivityThread.main(ActivityThread.java:5041)
                                                                           at java.lang.reflect.Method.invokeNative(Native Method)
                                                                           at java.lang.reflect.Method.invoke(Method.java:511)
                                                                           at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:816)
                                                                           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:582)

代码如下:

  初始化:  

if(this.executorService == null)//executorService为一个类对象
            this.executorService = Executors.newFixedThreadPool(2);

  调用部分:

 void smoothScrollTo(final int x, final int y) {
        this.executorService.execute(new Runnable() {
            @Override
            public void run() {
                ...
            }
 }

  内存溢出,我理解就是对象所需使用的内存大于了它本该拥有的最大额。比如此题的情景,线程池声明了最大容量为2的线程数,但在运行完之后创建的线程未被释放。至于原因,我到现在还是一知半解,有人说是ExecutorService这个类本身的缺陷,也有人推荐使用新的API。
  内存泄漏,即对象在错误或不严谨的代码编写的情况下,内存无法或不及时的释放。比如安卓中使用某个Activity对象当作context引用进行“传值”,这会造成如果当前activity因为某些原因没有被释放,那么被引用的那个Activity也会无法被虚拟机释放,即使它已经不需要存在了。
  
  我的解决方法
  1.将executorService 声明为静态类成员变量:

    private static ExecutorService executorService;

  2.初始化部分作同步块,容量可以适当增加如下:

        synchronized (DirectionalViewPager.class){
            if(executorService == null)
                executorService = Executors.newFixedThreadPool(7);
        }

  分析:
  

你可能感兴趣的:(JAVA学习)