Я вижу этот поток в моем jstack, который, кажется, не движется вообще. Любые указатели на то, как понять, почему он застрял? Я не вижу никаких замков или чего-то еще, единственной подозрительной вещью является ссылка "Object.wait()".
"main" prio=10 tid=0x00007f3a8000b000 nid=0x942 in Object.wait() [0x00007f3a89539000]
java.lang.Thread.State: RUNNABLE
at org.joda.time.DateTimeZone.<clinit>(DateTimeZone.java:95)
at org.joda.time.format.DateTimeFormatter.withZoneUTC(DateTimeFormatter.java:301)
at com.amazonaws.auth.AWS4Signer.<clinit>(AWS4Signer.java:44)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at java.lang.Class.newInstance0(Class.java:372)
at java.lang.Class.newInstance(Class.java:325)
at com.amazonaws.auth.SignerFactory.createSigner(SignerFactory.java:121)
at com.amazonaws.auth.SignerFactory.lookupAndCreateSigner(SignerFactory.java:107)
at com.amazonaws.auth.SignerFactory.getSigner(SignerFactory.java:80)
at com.amazonaws.AmazonWebServiceClient.computeSignerByServiceRegion(AmazonWebServiceClient.java:311)
at com.amazonaws.AmazonWebServiceClient.computeSignerByURI(AmazonWebServiceClient.java:284)
at com.amazonaws.AmazonWebServiceClient.setEndpoint(AmazonWebServiceClient.java:160)
Кроме того, строка 95 в DateTimeZone.java в верхней части стека:
public static final DateTimeZone UTC = new FixedDateTimeZone("UTC", "UTC", 0, 0);
Есть еще один поток, который также застрял в подобном месте:
"FeatureManagerService" daemon prio=10 tid=0x00007f3a8056a800 nid=0x94f in Object.wait() [0x00007f3a84151000]
java.lang.Thread.State: RUNNABLE
at com.amazonaws.util.DateUtils.<clinit>(DateUtils.java:35)
at com.amazonaws.services.s3.internal.ServiceUtils.<clinit>(ServiceUtils.java:59)
at com.amazonaws.services.s3.internal.S3Signer.sign(S3Signer.java:123)
at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:348)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:245)
at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3711)
at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3664)
at com.amazonaws.services.s3.AmazonS3Client.listObjects(AmazonS3Client.java:620)
at com.amazonaws.services.s3.AmazonS3Client.listObjects(AmazonS3Client.java:603)
И DateUtils.java:35:
private static final DateTimeZone GMT = new FixedDateTimeZone("GMT", "GMT", 0, 0);
Я уже пробовал изучать его с помощью jvisualvm/jhat, но на самом деле не очень далеко.
Обратите внимание, что это живой процесс, а не тот, который я запускаю в своем отладчике локально, и после перезапуска он работает нормально, поэтому он кажется прерывистым.
Любая помощь будет оценена!
Благодарю!
Обновление с использованием смешанного режима в jstack, похоже, дает более глубокое понимание - он ждет pthread_cond_wait:
----------------- 2370 -----------------
0x00007f3a89115414 __pthread_cond_wait + 0xc4
0x00007f3a8833a03c _ZN13ObjectMonitor4waitElbP6Thread + 0x7dc
0x00007f3a88117fbb _ZN13instanceKlass15initialize_implE19instanceKlassHandleP6Thread + 0x36b
0x00007f3a881182ca _ZN13instanceKlass10initializeEP6Thread + 0x6a
0x00007f3a8814d3f3 _ZN18InterpreterRuntime4_newEP10JavaThreadP19constantPoolOopDesci + 0x143
0x00007f3a7d01d9ee * org.joda.time.DateTimeZone.<clinit>() bci:0 line:95 (Interpreted frame)
0x00007f3a7d0004f7 <StubRoutines>
...
Как было найдено @naumcho, это оказалось ошибкой (https://github.com/JodaOrg/joda-time/issues/171).
Основываясь на предоставленной информации (трассировки стека двух разных нитей + исходная строка), можно было заподозрить тупик, потому что оба потока пытаются создать экземпляр нового объекта с FixedDateTimeZone
типом FixedDateTimeZone
.
Следующий шаг, чтобы подтвердить, что будет использовать GDB для проверки кадров стека вокруг __pthread_cond_wait()
.
Может быть, это не застряло. Он просто вызывает новую дату DateTimeZone() в цикле, а конструктор выполняет некоторые вычисления. Каждый раз, когда вы смотрите на этот поток, он находится внутри DateTimeZone(), но каждый раз он отличается от DateTimeZone().
Который затем отбрасывается. Случилось со мной несколько раз.