Как определить блокировку между потоками в Java VisualVM

#java #jvm #profiling #visualvm #jvisualvm

#java #jvm #профилирование #visualvm #jvisualvm

Вопрос:

После внедрения многопоточности я не вижу никакого увеличения скорости в моем проекте. Я предполагаю, что это связано с синхронизацией между каждым потоком. Чтобы определить это, я надеюсь использовать визуальное профилирование виртуальной машины, и, как показано ниже, оно определяет существенную синхронизацию / блокировку в каждом потоке.

Однако получение дампа потока в точке, где потоки заблокированы, показывает, что потоки блокируются на org.netbeans.lib.profiler.server.ProfilerRuntime.copyLocalBuffer(ProfilerRuntime.java:124), который, по-видимому, является внутренним методом для профилировщика. Как я могу определить реальные точки соприкосновения из этого, или существуют другие методы определения того, где блокируются эти потоки?

Скриншот VisualVM

 Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.121-b13 mixed mode):

"pool-1-thread-4" #32 prio=5 os_prio=31 tid=0x00007ff97796a000 nid=0x6603 runnable [0x000070000a310000]
   java.lang.Thread.State: RUNNABLE
    at org.netbeans.lib.profiler.server.ProfilerRuntimeCPUFullInstr.methodEntry(ProfilerRuntimeCPUFullInstr.java:139)
    at org.eclipse.emf.ecore.util.EContentsEList.basicIterator(EContentsEList.java:266)
    at org.eclipse.emf.ecore.util.EcoreUtil$ProperContentIterator.<init>(EcoreUtil.java:1359)
    at org.eclipse.emf.ecore.util.EcoreUtil$ProperContentIterator.<init>(EcoreUtil.java:1349)
    at org.eclipse.emf.ecore.resource.impl.ResourceImpl$5.getChildren(ResourceImpl.java:543)
    at org.eclipse.emf.common.util.AbstractTreeIterator.next(AbstractTreeIterator.java:143)
    at org.eclipse.emf.ecore.resource.impl.ResourceImpl.getEObjectByID(ResourceImpl.java:861)
    at org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.getEObjectByID(XMLResourceImpl.java:653)
    at org.eclipse.emf.ecore.resource.impl.ResourceImpl.getEObject(ResourceImpl.java:799)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.setValueFromId(XMLHandler.java:2868)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.setAttribValue(XMLHandler.java:2773)
    at org.eclipse.emf.ecore.xmi.impl.SAXXMIHandler.handleObjectAttribs(SAXXMIHandler.java:79)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.createObjectFromFactory(XMLHandler.java:2247)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.createObjectFromFeatureType(XMLHandler.java:2213)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.createObject(XMLHandler.java:2089)
    at org.eclipse.emf.ecore.xmi.impl.XMIHandler.createObject(XMIHandler.java:151)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.handleFeature(XMLHandler.java:1894)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.processElement(XMLHandler.java:1048)
    at org.eclipse.emf.ecore.xmi.impl.XMIHandler.processElement(XMIHandler.java:82)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.startElement(XMLHandler.java:1026)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.startElement(XMLHandler.java:720)
    at org.eclipse.emf.ecore.xmi.impl.XMIHandler.startElement(XMIHandler.java:190)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:509)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(XMLDocumentFragmentScannerImpl.java:1359)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2784)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:602)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:505)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:841)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:770)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:643)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl.parse(SAXParserImpl.java:327)
    at org.eclipse.emf.ecore.xmi.impl.XMLLoadImpl.load(Redefined)
    at org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.doLoad(Redefined)
    at org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(Redefined)
    at org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(Redefined)
    at parallel.xmi.parser.App$1.run(App.java:154)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:618)
    at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
    - <0x00000006800b7b38> (a java.util.concurrent.ThreadPoolExecutor$Worker)

"pool-1-thread-3" #31 prio=5 os_prio=31 tid=0x00007ff975913800 nid=0x9b03 runnable [0x000070000a20d000]
   java.lang.Thread.State: RUNNABLE
    at org.netbeans.lib.profiler.server.ProfilerRuntimeCPUFullInstr.methodExit(ProfilerRuntimeCPUFullInstr.java:174)
    at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eSettingDelegate(BasicEObjectImpl.java:1565)
    at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjectImpl.java:1027)
    at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjectImpl.java:1015)
    at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjectImpl.java:1003)
    at org.eclipse.emf.ecore.util.EContentsEList$FeatureIteratorImpl.hasNext(EContentsEList.java:439)
    at org.eclipse.emf.ecore.util.EcoreUtil$ProperContentIterator.hasNext(EcoreUtil.java:1366)
    at org.eclipse.emf.common.util.AbstractTreeIterator.next(AbstractTreeIterator.java:144)
    at org.eclipse.emf.ecore.resource.impl.ResourceImpl.getEObjectByID(ResourceImpl.java:861)
    at org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.getEObjectByID(XMLResourceImpl.java:653)
    at org.eclipse.emf.ecore.resource.impl.ResourceImpl.getEObject(ResourceImpl.java:799)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.setValueFromId(XMLHandler.java:2868)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.setAttribValue(XMLHandler.java:2773)
    at org.eclipse.emf.ecore.xmi.impl.SAXXMIHandler.handleObjectAttribs(SAXXMIHandler.java:79)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.createObjectFromFactory(XMLHandler.java:2247)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.createObjectFromFeatureType(XMLHandler.java:2213)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.createObject(XMLHandler.java:2089)
    at org.eclipse.emf.ecore.xmi.impl.XMIHandler.createObject(XMIHandler.java:151)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.handleFeature(XMLHandler.java:1894)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.processElement(XMLHandler.java:1048)
    at org.eclipse.emf.ecore.xmi.impl.XMIHandler.processElement(XMIHandler.java:82)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.startElement(XMLHandler.java:1026)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.startElement(XMLHandler.java:720)
    at org.eclipse.emf.ecore.xmi.impl.XMIHandler.startElement(XMIHandler.java:190)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:509)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(XMLDocumentFragmentScannerImpl.java:1359)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2784)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:602)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:505)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:841)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:770)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:643)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl.parse(SAXParserImpl.java:327)
    at org.eclipse.emf.ecore.xmi.impl.XMLLoadImpl.load(Redefined)
    at org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.doLoad(Redefined)
    at org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(Redefined)
    at org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(Redefined)
    at parallel.xmi.parser.App$1.run(App.java:154)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:618)
    at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
    - <0x00000006800b7ad8> (a java.util.concurrent.ThreadPoolExecutor$Worker)

"pool-1-thread-2" #30 prio=5 os_prio=31 tid=0x00007ff975851000 nid=0x9d03 runnable [0x000070000a10a000]
   java.lang.Thread.State: RUNNABLE
    at org.netbeans.lib.profiler.server.ProfilerRuntimeCPUFullInstr.methodEntry(ProfilerRuntimeCPUFullInstr.java:139)
    at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eContents(BasicEObjectImpl.java:812)
    at org.eclipse.emf.ecore.util.EcoreUtil$ProperContentIterator.<init>(EcoreUtil.java:1357)
    at org.eclipse.emf.ecore.util.EcoreUtil$ProperContentIterator.<init>(EcoreUtil.java:1349)
    at org.eclipse.emf.ecore.resource.impl.ResourceImpl$5.getChildren(ResourceImpl.java:543)
    at org.eclipse.emf.common.util.AbstractTreeIterator.next(AbstractTreeIterator.java:143)
    at org.eclipse.emf.ecore.resource.impl.ResourceImpl.getEObjectByID(ResourceImpl.java:861)
    at org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.getEObjectByID(XMLResourceImpl.java:653)
    at org.eclipse.emf.ecore.resource.impl.ResourceImpl.getEObject(ResourceImpl.java:799)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.setValueFromId(XMLHandler.java:2868)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.setAttribValue(XMLHandler.java:2773)
    at org.eclipse.emf.ecore.xmi.impl.SAXXMIHandler.handleObjectAttribs(SAXXMIHandler.java:79)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.createObjectFromFactory(XMLHandler.java:2247)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.createObjectFromFeatureType(XMLHandler.java:2213)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.createObject(XMLHandler.java:2089)
    at org.eclipse.emf.ecore.xmi.impl.XMIHandler.createObject(XMIHandler.java:151)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.handleFeature(XMLHandler.java:1894)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.processElement(XMLHandler.java:1048)
    at org.eclipse.emf.ecore.xmi.impl.XMIHandler.processElement(XMIHandler.java:82)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.startElement(XMLHandler.java:1026)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.startElement(XMLHandler.java:720)
    at org.eclipse.emf.ecore.xmi.impl.XMIHandler.startElement(XMIHandler.java:190)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:509)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(XMLDocumentFragmentScannerImpl.java:1359)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2784)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:602)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:505)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:841)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:770)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:643)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl.parse(SAXParserImpl.java:327)
    at org.eclipse.emf.ecore.xmi.impl.XMLLoadImpl.load(Redefined)
    at org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.doLoad(Redefined)
    at org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(Redefined)
    at org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(Redefined)
    at parallel.xmi.parser.App$1.run(App.java:154)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:618)
    at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
    - <0x00000006800b7b88> (a java.util.concurrent.ThreadPoolExecutor$Worker)

"pool-1-thread-1" #29 prio=5 os_prio=31 tid=0x00007ff97580c000 nid=0xa10b runnable [0x0000700009cfe000]
   java.lang.Thread.State: RUNNABLE
    at org.netbeans.lib.profiler.server.ProfilerRuntimeCPUFullInstr.methodExit(ProfilerRuntimeCPUFullInstr.java:174)
    at org.eclipse.emf.ecore.impl.DynamicEObjectImpl.eSettings(DynamicEObjectImpl.java:246)
    at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eDynamicIsSet(BasicEObjectImpl.java:1275)
    at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eIsSet(BasicEObjectImpl.java:1255)
    at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eIsSet(BasicEObjectImpl.java:1245)
    at org.eclipse.emf.ecore.util.EContentsEList$FeatureIteratorImpl.hasNext(EContentsEList.java:437)
    at org.eclipse.emf.ecore.util.EcoreUtil$ProperContentIterator.hasNext(EcoreUtil.java:1366)
    at org.eclipse.emf.common.util.AbstractTreeIterator.next(AbstractTreeIterator.java:144)
    at org.eclipse.emf.ecore.resource.impl.ResourceImpl.getEObjectByID(ResourceImpl.java:861)
    at org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.getEObjectByID(XMLResourceImpl.java:653)
    at org.eclipse.emf.ecore.resource.impl.ResourceImpl.getEObject(ResourceImpl.java:799)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.setValueFromId(XMLHandler.java:2868)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.setAttribValue(XMLHandler.java:2773)
    at org.eclipse.emf.ecore.xmi.impl.SAXXMIHandler.handleObjectAttribs(SAXXMIHandler.java:79)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.createObjectFromFactory(XMLHandler.java:2247)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.createObjectFromFeatureType(XMLHandler.java:2213)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.createObject(XMLHandler.java:2089)
    at org.eclipse.emf.ecore.xmi.impl.XMIHandler.createObject(XMIHandler.java:151)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.handleFeature(XMLHandler.java:1894)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.processElement(XMLHandler.java:1048)
    at org.eclipse.emf.ecore.xmi.impl.XMIHandler.processElement(XMIHandler.java:82)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.startElement(XMLHandler.java:1026)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.startElement(XMLHandler.java:720)
    at org.eclipse.emf.ecore.xmi.impl.XMIHandler.startElement(XMIHandler.java:190)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:509)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(XMLDocumentFragmentScannerImpl.java:1359)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2784)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:602)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:505)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:841)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:770)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:643)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl.parse(SAXParserImpl.java:327)
    at org.eclipse.emf.ecore.xmi.impl.XMLLoadImpl.load(Redefined)
    at org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.doLoad(Redefined)
    at org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(Redefined)
    at org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(Redefined)
    at parallel.xmi.parser.App$1.run(App.java:154)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:618)
    at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
    - <0x00000006800b7878> (a java.util.concurrent.ThreadPoolExecutor$Worker)
  

Спасибо

Комментарии:

1. Вы можете избежать использования профилировщика и взять дамп потока с помощью jstack и посмотреть, поможет ли это вам увидеть, где потоки заблокированы.

2. Там также замечательно github.com/jvm-profiling-tools/async-profiler на случай, если вам нужно выполнить профилирование процессора с низкой нагрузкой (поскольку вы упомянули, что «не видите никакого прироста скорости»).