1. 启动netty server 等待接受客户端连接
1 package io.netty.example.myTest.nio; 2 import java.io.IOException; 3 import java.net.InetSocketAddress; 4 import java.nio.channels.SelectionKey; 5 import java.nio.channels.Selector; 6 import java.nio.channels.ServerSocketChannel; 7 import java.util.Iterator; 8 import java.util.Set; 9 10 public class ServerNIO { 11 static Selector selector; 12 static ServerSocketChannel serverSocketChannel; 13 public static void main (String[] args) { 14 try { 15 selector = Selector.open(); 16 serverSocketChannel = ServerSocketChannel.open(); 17 serverSocketChannel.socket().bind(new InetSocketAddress("localhost", 9999)); 18 serverSocketChannel.configureBlocking(false); 19 SelectionKey selectionKey = serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); 20 while ( true ) { 21 selector.select(1000); 22 Set<SelectionKey> keys = selector.selectedKeys(); 23 Iterator<SelectionKey> iKeys = keys.iterator(); 24 SelectionKey selectionKey1 = null; 25 while (iKeys.hasNext()) { 26 selectionKey1 = iKeys.next(); 27 iKeys.remove(); 28 if (selectionKey1.isValid()) { 29 if (selectionKey1.isAcceptable()) { 30 Thread.sleep(10000); 31 System.out.println("accept"); 32 } 33 } 34 } 35 } 36 }catch (IOException ioe) { 37 38 } catch (InterruptedException e) { 39 e.printStackTrace(); 40 } 41 } 42 }
jps 查看进程号
jstack查看进程状态,处于RUNNABLE 并在ServerNIO.main(ServerNIO.java:21) 处,调用栈看到 EPollArrayWrapper.epollWait
[root@izm5e8p93wtcdi53pzqhi7z ~]# jstack 29266
2018-07-30 13:06:39 Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.181-b13 mixed mode): "Attach Listener" #8 daemon prio=9 os_prio=0 tid=0x00007f2e28001000 nid=0x7289 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Service Thread" #7 daemon prio=9 os_prio=0 tid=0x00007f2e580ba000 nid=0x725c runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE "C1 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007f2e580b7000 nid=0x725b waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007f2e580b4000 nid=0x725a waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007f2e580b2800 nid=0x7259 runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007f2e5807f800 nid=0x7258 in Object.wait() [0x00007f2e5c4de000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x00000000f6708ed0> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144) - locked <0x00000000f6708ed0> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:216) "Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007f2e5807d000 nid=0x7257 in Object.wait() [0x00007f2e5c5df000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x00000000f6706bf8> (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Object.java:502) at java.lang.ref.Reference.tryHandlePending(Reference.java:191) - locked <0x00000000f6706bf8> (a java.lang.ref.Reference$Lock) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153) "main" #1 prio=5 os_prio=0 tid=0x00007f2e58009000 nid=0x7253 runnable [0x00007f2e61a9a000] java.lang.Thread.State: RUNNABLE at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method) at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269) at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93) at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86) - locked <0x00000000f6775890> (a sun.nio.ch.Util$3) - locked <0x00000000f6775808> (a java.util.Collections$UnmodifiableSet) - locked <0x00000000f6770c10> (a sun.nio.ch.EPollSelectorImpl) at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97) at ServerNIO.main(ServerNIO.java:21) "VM Thread" os_prio=0 tid=0x00007f2e58073000 nid=0x7256 runnable "GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007f2e5801e800 nid=0x7254 runnable "GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007f2e58020000 nid=0x7255 runnable "VM Periodic Task Thread" os_prio=0 tid=0x00007f2e580be800 nid=0x725d waiting on condition JNI global references: 14
2. 启动一个客户端,仅连接
package io.netty.example.myTest.nio; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.Iterator; import java.util.Set; public class ClientNIO { static Selector selector; static SocketChannel socketChannel; public static void main (String[] args) { try { socketChannel = SocketChannel.open(); socketChannel.connect(new InetSocketAddress("localhost", 9999)); }catch (IOException ioe) { } } }
连接后断开,再次运行[root@izm5e8p93wtcdi53pzqhi7z ~]# jstack 29266,可以看到ServerNIO.main(ServerNIO.java:30) 此时已经连接并且在sleep,java.lang.Thread.State: TIMED_WAITING (sleeping)
2018-07-30 13:20:08 Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.181-b13 mixed mode): "Attach Listener" #8 daemon prio=9 os_prio=0 tid=0x00007f2e28001000 nid=0x7289 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Service Thread" #7 daemon prio=9 os_prio=0 tid=0x00007f2e580ba000 nid=0x725c runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE "C1 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007f2e580b7000 nid=0x725b waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007f2e580b4000 nid=0x725a waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007f2e580b2800 nid=0x7259 runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007f2e5807f800 nid=0x7258 in Object.wait() [0x00007f2e5c4de000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x00000000f6708ed0> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144) - locked <0x00000000f6708ed0> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:216) "Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007f2e5807d000 nid=0x7257 in Object.wait() [0x00007f2e5c5df000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x00000000f6706bf8> (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Object.java:502) at java.lang.ref.Reference.tryHandlePending(Reference.java:191) - locked <0x00000000f6706bf8> (a java.lang.ref.Reference$Lock) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153) "main" #1 prio=5 os_prio=0 tid=0x00007f2e58009000 nid=0x7253 waiting on condition [0x00007f2e61a9a000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at ServerNIO.main(ServerNIO.java:30) "VM Thread" os_prio=0 tid=0x00007f2e58073000 nid=0x7256 runnable "GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007f2e5801e800 nid=0x7254 runnable "GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007f2e58020000 nid=0x7255 runnable "VM Periodic Task Thread" os_prio=0 tid=0x00007f2e580be800 nid=0x725d waiting on condition JNI global references: 14
3. CPU过高(忙于计算,忙于GC - https://www.jianshu.com/p/f93b6013b965)
忙于死循环类测试
1 package io.netty.example.myTest; 2 3 import java.util.concurrent.ExecutorService; 4 import java.util.concurrent.Executors; 5 6 public class ThreadTest { 7 public static void main (String[] args) { 8 ExecutorService executorService = Executors.newSingleThreadExecutor(); 9 executorService.execute(new Runnable() { 10 @Override 11 public void run() { 12 int i = 0; 13 while ( true ) { 14 i++; 15 i--; 16 } 17 } 18 }); 19 } 20 }
top -Hp 29926
printf %x 29938 ==》 74f2, 根据该线程号可以找到nid=0x74f2的信息,进而看到 ThreadTest$1.run(ThreadTest.java:13)
2018-07-30 13:41:00 Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.181-b13 mixed mode): "Attach Listener" #10 daemon prio=9 os_prio=0 tid=0x00007fcdc4001000 nid=0x7519 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "DestroyJavaVM" #9 prio=5 os_prio=0 tid=0x00007fcdfc009000 nid=0x74e7 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "pool-1-thread-1" #8 prio=5 os_prio=0 tid=0x00007fcdfc0ef800 nid=0x74f2 runnable [0x00007fcde75f4000] java.lang.Thread.State: RUNNABLE at ThreadTest$1.run(ThreadTest.java:13) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) "Service Thread" #7 daemon prio=9 os_prio=0 tid=0x00007fcdfc0c2000 nid=0x74f0 runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE "C1 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007fcdfc0b7000 nid=0x74ef waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007fcdfc0b4000 nid=0x74ee waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007fcdfc0b2800 nid=0x74ed runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007fcdfc07f800 nid=0x74ec in Object.wait() [0x00007fcde7bfa000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x00000000f6708ed0> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144) - locked <0x00000000f6708ed0> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:216) "Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007fcdfc07d000 nid=0x74eb in Object.wait() [0x00007fcde7cfb000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x00000000f6706bf8> (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Object.java:502) at java.lang.ref.Reference.tryHandlePending(Reference.java:191) - locked <0x00000000f6706bf8> (a java.lang.ref.Reference$Lock) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153) "VM Thread" os_prio=0 tid=0x00007fcdfc073000 nid=0x74ea runnable "GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007fcdfc01e800 nid=0x74e8 runnable "GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007fcdfc020000 nid=0x74e9 runnable "VM Periodic Task Thread" os_prio=0 tid=0x00007fcdfc0c7000 nid=0x74f1 waiting on condition JNI global references: 5
4. 对于3改成不用线程池再看一下
new Thread(new Runnable() { @Override public void run() { int i = 0; while ( true ) { i++; i--; } } }).start();
截取部分内容,看到区别
"Thread-0" #8 prio=5 os_prio=0 tid=0x00007fb8000df800 nid=0x757a runnable [0x00007fb7f02f1000] java.lang.Thread.State: RUNNABLE at ThreadTest$1.run(ThreadTest.java:9) at java.lang.Thread.run(Thread.java:748)
5. wait的情况
1 import java.util.concurrent.ExecutorService; 2 import java.util.concurrent.Executors; 3 4 public class ThreadTest { 5 public static void main (String[] args) { 6 ExecutorService executorService = Executors.newFixedThreadPool(10); 7 executorService.execute(new Runnable() { 8 @Override 9 public void run() { 10 Object lock = new Object(); 11 synchronized ( lock ) { 12 try { 13 lock.wait(); 14 } catch (InterruptedException e) { 15 e.printStackTrace(); 16 } 17 } 18 } 19 }); 20 } 21 }
"pool-1-thread-1" #8 prio=5 os_prio=0 tid=0x00007f88880ef800 nid=0x75c5 in Object.wait() [0x00007f887539d000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x00000000f67a8010> (a java.lang.Object) at java.lang.Object.wait(Object.java:502) at ThreadTest$1.run(ThreadTest.java:13) - locked <0x00000000f67a8010> (a java.lang.Object) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748)
6. 带时间的wait(10000)
"pool-1-thread-1" #8 prio=5 os_prio=0 tid=0x00007f498c0f7800 nid=0x7607 in Object.wait() [0x00007f4977cfb000] java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x00000000f67a8010> (a java.lang.Object) at ThreadTest$1.run(ThreadTest.java:13) - locked <0x00000000f67a8010> (a java.lang.Object) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748)
7. lock
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class ThreadTest { public static void main (String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(10); executorService.execute(new Runnable() { @Override public void run() { Lock lock = new ReentrantLock(); lock.lock(); } }); } }
"pool-1-thread-1" #8 prio=5 os_prio=0 tid=0x00007fbe9c0ff800 nid=0x763f waiting on condition [0x00007fbe8cbfa000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x00000000f675d9b0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748)
8.死锁测试
1 import java.util.concurrent.ExecutorService; 2 import java.util.concurrent.Executors; 3 4 public class ThreadTest { 5 public static void main (String[] args) { 6 ExecutorService executorService = Executors.newFixedThreadPool(10); 7 final Object A = new Object(); 8 final Object B = new Object(); 9 10 final Runnable command1 = new Runnable() { 11 @Override 12 public void run() { 13 synchronized ( A ) { 14 try { 15 Thread.sleep(10000); 16 } catch (InterruptedException e) { 17 e.printStackTrace(); 18 } 19 synchronized ( B ) { 20 21 } 22 } 23 } 24 }; 25 final Runnable command2 = new Runnable() { 26 @Override 27 public void run() { 28 synchronized ( B ) { 29 try { 30 Thread.sleep(10000); 31 } catch (InterruptedException e) { 32 e.printStackTrace(); 33 } 34 synchronized ( A ) { 35 36 } 37 } 38 } 39 }; 40 executorService.execute(command1); 41 executorService.execute(command2); 42 } 43 }
2018-07-30 14:09:06 Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.181-b13 mixed mode): "Attach Listener" #11 daemon prio=9 os_prio=0 tid=0x00007f3ef8001000 nid=0x7728 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "DestroyJavaVM" #10 prio=5 os_prio=0 tid=0x00007f3f28009000 nid=0x7703 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "pool-1-thread-2" #9 prio=5 os_prio=0 tid=0x00007f3f280e9000 nid=0x770f waiting for monitor entry [0x00007f3f18af9000] java.lang.Thread.State: BLOCKED (on object monitor) at ThreadTest$2.run(ThreadTest.java:36) - waiting to lock <0x00000000f675de30> (a java.lang.Object) - locked <0x00000000f675de40> (a java.lang.Object) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) "pool-1-thread-1" #8 prio=5 os_prio=0 tid=0x00007f3f280e7800 nid=0x770e waiting for monitor entry [0x00007f3f18bfa000] java.lang.Thread.State: BLOCKED (on object monitor) at ThreadTest$1.run(ThreadTest.java:21) - waiting to lock <0x00000000f675de40> (a java.lang.Object) - locked <0x00000000f675de30> (a java.lang.Object) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) "Service Thread" #7 daemon prio=9 os_prio=0 tid=0x00007f3f280ba000 nid=0x770c runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE "C1 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007f3f280b7000 nid=0x770b waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007f3f280b4000 nid=0x770a waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007f3f280b2800 nid=0x7709 runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007f3f2807f800 nid=0x7708 in Object.wait() [0x00007f3f2c28e000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x00000000f6708ed0> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144) - locked <0x00000000f6708ed0> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:216) "Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007f3f2807d000 nid=0x7707 in Object.wait() [0x00007f3f2c38f000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x00000000f6706bf8> (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Object.java:502) at java.lang.ref.Reference.tryHandlePending(Reference.java:191) - locked <0x00000000f6706bf8> (a java.lang.ref.Reference$Lock) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153) "VM Thread" os_prio=0 tid=0x00007f3f28073000 nid=0x7706 runnable "GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007f3f2801e800 nid=0x7704 runnable "GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007f3f28020000 nid=0x7705 runnable "VM Periodic Task Thread" os_prio=0 tid=0x00007f3f280bf000 nid=0x770d waiting on condition JNI global references: 5 Found one Java-level deadlock: ============================= "pool-1-thread-2": waiting to lock monitor 0x00007f3f040062c8 (object 0x00000000f675de30, a java.lang.Object), which is held by "pool-1-thread-1" "pool-1-thread-1": waiting to lock monitor 0x00007f3f040038d8 (object 0x00000000f675de40, a java.lang.Object), which is held by "pool-1-thread-2" Java stack information for the threads listed above: =================================================== "pool-1-thread-2": at ThreadTest$2.run(ThreadTest.java:36) - waiting to lock <0x00000000f675de30> (a java.lang.Object) - locked <0x00000000f675de40> (a java.lang.Object) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) "pool-1-thread-1": at ThreadTest$1.run(ThreadTest.java:21) - waiting to lock <0x00000000f675de40> (a java.lang.Object) - locked <0x00000000f675de30> (a java.lang.Object) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) Found 1 deadlock.
9. 内存溢出
参数简介
-Xmn:整个JVM内存大小=年轻代大小 + 年老代大小 + 持久代大小。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。
-Xss128k:设置每个线程的堆栈大小,在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右
-XX:NewRatio=4:设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)。设置为4,则年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5
-XX:SurvivorRatio=4:设置年轻代中Eden区与Survivor区的大小比值。设置为4,则两个Survivor区与一个Eden区的比值为2:4,一个Survivor区占整个年轻代的1/6
-XX:MaxTenuringThreshold=0:设置垃圾最大年龄。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。
如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概率。
吞吐量优先的并行收集器
-XX:+UseParallelGC:选择垃圾收集器为并行收集器。此配置仅对年轻代有效 -XX:ParallelGCThreads=20:配置并行收集器的线程数,即:同时多少个线程一起进行垃圾回收。此值最好配置与处理器数目相等 -XX:+UseParallelOldGC:配置年老代垃圾收集方式为并行收集 -XX:MaxGCPauseMillis=100:设置每次年轻代垃圾回收的最长时间,如果无法满足此时间,JVM会自动调整年轻代大小,以满足此值 -XX:+UseAdaptiveSizePolicy:设置此选项后,并行收集器会自动选择年轻代区大小和相应的Survivor区比例,以达到目标系统规定的最低相应时间或者收集频率等,此值建议使用并行收集器时,一直打开
java -Xmx20m -Xms20m -Xmn10m -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseParallelOldGC -XX:+PrintGCDetails -cp . ThreadTest
1 import java.util.HashSet; 2 import java.util.concurrent.ExecutorService; 3 import java.util.concurrent.Executors; 4 5 public class ThreadTest { 6 public static void main (String[] args) { 7 final HashSet hs = new HashSet(); 8 ExecutorService executorService = Executors.newFixedThreadPool(10); 9 final Runnable command = new Runnable() { 10 @Override 11 public void run() { 12 while ( true ) { 13 try { 14 Thread.sleep( 100 ); 15 } catch (InterruptedException e) { 16 e.printStackTrace(); 17 } 18 hs.add( new Object[1024 * 10]); 19 } 20 } 21 }; 22 executorService.execute(command); 23 } 24 }
[GC (Allocation Failure) [PSYoungGen: 8156K->1016K(9216K)] 8156K->7626K(19456K), 0.0071395 secs] [Times: user=0.00 sys=0.01, real=0.01 secs]
[Full GC (Ergonomics) [PSYoungGen: 1016K->0K(9216K)] [ParOldGen: 6610K->7556K(10240K)] 7626K->7556K(19456K), [Metaspace: 2637K->2637K(1056768K)], 0.0553513 secs] [Times: user=0.11 sys=0.00, real=0.05 secs]
[Full GC (Ergonomics) [PSYoungGen: 8156K->5562K(9216K)] [ParOldGen: 7556K->10111K(10240K)] 15712K->15674K(19456K), [Metaspace: 2643K->2643K(1056768K)], 0.0361699 secs] [Times: user=0.06 sys=0.00, real=0.03 secs]
[Full GC (Ergonomics) [PSYoungGen: 8158K->8125K(9216K)] [ParOldGen: 10111K->10111K(10240K)] 18270K->18237K(19456K), [Metaspace: 2643K->2643K(1056768K)], 0.0401159 secs] [Times: user=0.08 sys=0.00, real=0.04 secs]
[Full GC (Ergonomics) [PSYoungGen: 8192K->8165K(9216K)] [ParOldGen: 10111K->10111K(10240K)] 18303K->18277K(19456K), [Metaspace: 2643K->2643K(1056768K)], 0.0298122 secs] [Times: user=0.05 sys=0.00, real=0.03 secs]
[Full GC (Ergonomics) [PSYoungGen: 8192K->8165K(9216K)] [ParOldGen: 10231K->10231K(10240K)] 18423K->18397K(19456K), [Metaspace: 2643K->2643K(1056768K)], 0.0359396 secs] [Times: user=0.07 sys=0.01, real=0.04 secs]
[Full GC (Allocation Failure) [PSYoungGen: 8165K->8165K(9216K)] [ParOldGen: 10231K->10231K(10240K)] 18397K->18397K(19456K), [Metaspace: 2643K->2643K(1056768K)], 0.0313513 secs] [Times: user=0.06 sys=0.00, real=0.03 secs]
Exception in thread "pool-1-thread-1" [Full GC (Ergonomics) [PSYoungGen: 8192K->0K(9216K)] [ParOldGen: 10234K->255K(10240K)] 18426K->255K(19456K), [Metaspace: 2667K->2667K(1056768K)], 0.0116908 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]
java.lang.OutOfMemoryError: Java heap space
at ThreadTest$1.run(ThreadTest.java:18)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Heap
PSYoungGen total 9216K, used 443K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
eden space 8192K, 5% used [0x00000000ff600000,0x00000000ff66ef10,0x00000000ffe00000)
from space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
to space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
ParOldGen total 10240K, used 255K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
object space 10240K, 2% used [0x00000000fec00000,0x00000000fec3feb8,0x00000000ff600000)
Metaspace used 2683K, capacity 4486K, committed 4864K, reserved 1056768K
class space used 292K, capacity 386K, committed 512K, reserved 1048576K
jinfo 31367
VM Flags: Non-default VM flags: -XX:CICompilerCount=2 -XX:InitialHeapSize=20971520 -XX:MaxHeapSize=20971520 -XX:MaxNewSize=10485760 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=10485760 -XX:OldSize=10485760 -XX:ParallelGCThreads=20 -XX:+PrintGCDetails -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC -XX:+UseParallelOldGC Command line: -Xmx20m -Xms20m -Xmn10m -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseParallelOldGC -XX:+PrintGCDetails
jmap -histo 31367
num #instances #bytes class name ---------------------------------------------- 1: 645 4861968 [Ljava.lang.Object; 2: 443 493928 [I 3: 1677 152136 [C
响应时间优先的收集器配置
-XX:+UseConcMarkSweepGC:设置年老代为并发收集 -XX:+UseParNewGC:设置年轻代为并行收集 -XX:CMSFullGCsBeforeCompaction:由于并发收集器不对内存空间进行压缩、整理,所以运行一段时间以后会产生“碎片”,使得运行效率降低。此值设置运行多少次GC以后对内存空间进行压缩、整理。 -XX:+UseCMSCompactAtFullCollection:打开对年老代的压缩。可能会影响性能,但是可以消除碎片
java -Xmx20m -Xms20m -Xmn10m -XX:ParallelGCThreads=20 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+PrintGCDetails -cp . ThreadTest
[GC (Allocation Failure) [ParNew: 8156K->1023K(9216K), 0.0515080 secs] 8156K->7627K(19456K), 0.0515731 secs] [Times: user=0.10 sys=0.00, real=0.05 secs] [GC (CMS Initial Mark) [1 CMS-initial-mark: 6603K(10240K)] 7667K(19456K), 0.0015729 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] [CMS-concurrent-mark-start] [CMS-concurrent-mark: 0.001/0.001 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [CMS-concurrent-preclean-start] [CMS-concurrent-preclean: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (CMS Final Remark) [YG occupancy: 1064 K (9216 K)][Rescan (parallel) , 0.0120069 secs][weak refs processing, 0.0000126 secs][class unloading, 0.0002688 secs][scrub symbol table, 0.0004252 secs][scrub string table, 0.0001109 secs][1 CMS-remark: 6603K(10240K)] 7667K(19456K), 0.0129012 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] [CMS-concurrent-sweep-start] [CMS-concurrent-sweep: 0.000/0.000 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] [CMS-concurrent-reset-start] [CMS-concurrent-reset: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] .... [CMS-concurrent-mark-start] [CMS-concurrent-mark: 0.002/0.002 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [CMS-concurrent-preclean-start] [CMS-concurrent-preclean: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [CMS-concurrent-abortable-preclean-start] [CMS-concurrent-abortable-preclean: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (CMS Final Remark) [YG occupancy: 9197 K (9216 K)][Rescan (parallel) , 0.0141205 secs][weak refs processing, 0.0000115 secs][class unloading, 0.0003192 secs][scrub symbol table, 0.0004989 secs][scrub string table, 0.0001190 secs][1 CMS-remark: 10214K(10240K)] 19412K(19456K), 0.0151344 secs] [Times: user=0.03 sys=0.00, real=0.02 secs] [CMS-concurrent-sweep-start] [CMS-concurrent-sweep: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [CMS-concurrent-reset-start] [CMS-concurrent-reset: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] ^CHeap par new generation total 9216K, used 9199K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000) eden space 8192K, 100% used [0x00000000fec00000, 0x00000000ff400000, 0x00000000ff400000) from space 1024K, 98% used [0x00000000ff500000, 0x00000000ff5fbcc0, 0x00000000ff600000) to space 1024K, 0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff500000) concurrent mark-sweep generation total 10240K, used 10214K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000) Metaspace used 2685K, capacity 4486K, committed 4864K, reserved 1056768K class space used 292K, capacity 386K, committed 512K, reserved 1048576K
10. 线程池相关
1 package io.netty.example.myTest; 2 3 import java.util.concurrent.*; 4 5 public class ThreadTest { 6 public static void main (String[] args) { 7 // 先2,然后queue,满了之后运行线程增加到max 8 //针对本例子,先创建2个线程,t1,t2进入线程池之后直接执行,t3加入阻塞队列,队列满,t4到来线程池扩张线程到max运行t4,t5到来无法处理,进入到reject 9 ExecutorService executorService = new ThreadPoolExecutor(2, 3, 10 0L, TimeUnit.MILLISECONDS, 11 new ArrayBlockingQueue<Runnable>(1), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy()); 12 Thread t1 = new Thread(new Runnable() { 13 @Override 14 public void run() { 15 int i = 0; 16 while (true) { 17 i++; 18 i--; 19 } 20 } 21 }, "1-test"); 22 Thread t2 = new Thread(new Runnable() { 23 @Override 24 public void run() { 25 int i = 0; 26 while (true) { 27 i++; 28 i--; 29 } 30 } 31 }, "2-test"); 32 Thread t3 = new Thread(new Runnable() { 33 @Override 34 public void run() { 35 int i = 0; 36 while (true) { 37 i++; 38 i--; 39 } 40 } 41 }, "3-test"); 42 Thread t4 = new Thread(new Runnable() { 43 @Override 44 public void run() { 45 int i = 0; 46 while (true) { 47 i++; 48 i--; 49 } 50 } 51 }, "4-test"); 52 Thread t5 = new Thread(new Runnable() { 53 @Override 54 public void run() { 55 int i = 0; 56 while (true) { 57 i++; 58 i--; 59 } 60 } 61 }, "5-test"); 62 executorService.execute(t1); 63 executorService.execute(t2); 64 executorService.execute(t3); 65 executorService.execute(t4); 66 executorService.execute(t5); 67 } 68 }
由于先创建2个线程,t1,t2进入线程池之后直接执行,t3加入阻塞队列,队列满,t4到来线程池扩张线程到max运行t4,t5到来无法处理,进入到reject,所以运行结果如下
Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task Thread[5-test,5,main] rejected from java.util.concurrent.ThreadPoolExecutor@27716f4[Running, pool size = 3, active threads = 3, queued tasks = 1, completed tasks = 0] at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063) at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830) at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379) at io.netty.example.myTest.ThreadTest.main(ThreadTest.java:66)
如果new ArrayBlockingQueue<Runnable>(1) 改为 new LinkedBlockingQueue<Runnable>(), 则缓存队列无界,不会报上面的错
11. CPU饱和
同样用上面的例子,改为无界队列
前面两个线程T1/T2在运行 "pool-1-thread-2" #14 prio=5 os_prio=0 tid=0x00007f43c40e9800 nid=0x7c4a runnable [0x00007f43aed13000] java.lang.Thread.State: RUNNABLE at ThreadTest$2.run(ThreadTest.java:24) at java.lang.Thread.run(Thread.java:748) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) "pool-1-thread-1" #13 prio=5 os_prio=0 tid=0x00007f43c40e7800 nid=0x7c49 runnable [0x00007f43aee14000] java.lang.Thread.State: RUNNABLE at ThreadTest$1.run(ThreadTest.java:14) at java.lang.Thread.run(Thread.java:748) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748)
[root@izm5e8p93wtcdi53pzqhi7z test]# cat /proc/cpuinfo 可以看到在两个CPU的情况下,%CPU最高达到200%
top -Hp 31805