问题描述
我的应用程序是使用JavaFX用Java 8编写的,它会截取屏幕快照或快照,并且两次生成此错误:
My application, written in Java 8 using JavaFX, takes screenshots, or rather, snapshots, and twice it generated this error:
java.lang.IllegalArgumentException: Unrecognized image loader: null
at javafx.scene.image.WritableImage.loadTkImage(WritableImage.java:240)
at javafx.scene.image.WritableImage.access$000(WritableImage.java:46)
at javafx.scene.image.WritableImage$1.loadTkImage(WritableImage.java:51)
at javafx.scene.Scene.doSnapshot(Scene.java:1236)
at javafx.scene.Node.doSnapshot(Node.java:1864)
at javafx.scene.Node.snapshot(Node.java:1942)
到目前为止,在我的应用程序中,我无法重现它.搜索此问题后,我发现了这一点:
So far, in my application, I wasn't able to reproduce it. Searching for this issue I found this:
https://bugs.openjdk.java.net/browse/JDK-8116783
指向:
https://bugs.openjdk.java.net/browse/JDK-8088198
这似乎是JavaFX中的一个公开错误:如果尺寸大于最大纹理大小,则会从快照引发异常".
It seems to be an open bug in JavaFX: "Exception thrown from snapshot if dimensions are larger than max texture size".
对该错误的描述说,它偶尔会发生.有人知道捕获异常并重试是一种好方法还是解决方法?
The description of the bug says that it happens occasionally. Does anybody know if catching the exception and retrying would be a good way or workaround it?
更新:当我尝试通过使屏幕截图很大来重现此错误时,我遇到了完全不同的错误:
Update: when I tried to reproduce this error by making the screenshot very big, I got a completely different error:
java.lang.NullPointerException
at com.sun.prism.impl.ps.BaseShaderContext.initLCDBuffer(BaseShaderContext.java:703)
at com.sun.prism.impl.ps.BaseShaderContext.validateLCDBuffer(BaseShaderContext.java:725)
at com.sun.prism.impl.ps.BaseShaderGraphics.initLCDSampleRT(BaseShaderGraphics.java:1925)
at com.sun.prism.impl.ps.BaseShaderGraphics.drawString(BaseShaderGraphics.java:2059)
at com.sun.javafx.webkit.prism.WCGraphicsPrismContext$10.doPaint(WCGraphicsPrismContext.java:936)
at com.sun.javafx.webkit.prism.WCGraphicsPrismContext$Composite.paint(WCGraphicsPrismContext.java:1500)
at com.sun.javafx.webkit.prism.WCGraphicsPrismContext$Composite.paint(WCGraphicsPrismContext.java:1485)
at com.sun.javafx.webkit.prism.WCGraphicsPrismContext.drawString(WCGraphicsPrismContext.java:948)
at com.sun.webkit.graphics.GraphicsDecoder.decode(GraphicsDecoder.java:299)
at com.sun.webkit.graphics.WCRenderQueue.decode(WCRenderQueue.java:92)
at com.sun.webkit.WebPage.paint2GC(WebPage.java:734)
at com.sun.webkit.WebPage.paint(WebPage.java:701)
at com.sun.javafx.sg.prism.web.NGWebView.renderContent(NGWebView.java:96)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.tk.quantum.QuantumToolkit$5.draw(QuantumToolkit.java:1393)
at com.sun.javafx.tk.quantum.QuantumToolkit$5.run(QuantumToolkit.java:1429)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
at com.sun.javafx.tk.RenderJob.run(RenderJob.java:58)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:125)
at java.lang.Thread.run(Thread.java:748)
类似地,这是一个根本没有调用触及我的代码的线程.
It similarly is a thread with no call touching my code at all.
推荐答案
TL; DR:
- 即使使用Oracle JVM,也请参阅: https://wiki.openjdk.java.net/pages/viewpage.action?pageId = 20415996
- 使用
-Dprism.poolstats = true -Dprism.verbose = true
检查您的maxvram限制并查看您实际消耗了多少vram - 将
-Dprism.maxvram = xxxxM
设置为较低的值可能有助于重现该问题 - 将
-Dprism.maxvram = xxxxM
设置为更高的值可能有助于解决该问题
- even if using Oracle JVM, see: https://wiki.openjdk.java.net/pages/viewpage.action?pageId=20415996
- use
-Dprism.poolstats=true -Dprism.verbose=true
to check your maxvram limit and to see how much vram you actually consume - setting
-Dprism.maxvram=xxxxM
to lower value might help to reproduce the problem - setting
-Dprism.maxvram=xxxxM
to higher value might help to solve the problem
我的案子(针对任何有兴趣的人)
正如上面链接中所建议的那样,我使用了 -Dprism.poolstats = true -Dprism.verbose = true
,并发现maxvram足够高.无论如何,可以肯定的是,我添加了 -Dprism.maxvram = 1024M -Dprism.targetvram = 512M
,但这没有帮助.有足够的内存,但分配失败,并出现以下错误:
As suggested in the link above I used -Dprism.poolstats=true -Dprism.verbose=true
and found that maxvram is high enough. Anyway, to be really sure, I added -Dprism.maxvram=1024M -Dprism.targetvram=512M
but it didn't help. There was enough memory but the allocation kept failing with the following errors:
D3D Vram Pool: 66.929.834 used (12,5%), 81.273.002 target (15,1%), 536.870.912 max
36 total resources being managed
average resource age is 12,6 frames
0 resources at maximum supported age (0,0%)
5 resources marked permanent (13,9%)
0 resources have had mismatched locks (0,0%)
0 resources locked (0,0%)
31 resources contain interesting data (86,1%)
0 resources disappeared (0,0%)
Growing pool D3D Vram Pool target to 116.658.814
Growing pool D3D Vram Pool target to 131.338.878
Growing pool D3D Vram Pool target to 159.043.730
D3D hresult failed :D3D_ERROR ffffffff8007000e
java.lang.Exception: Stack trace
at com.sun.prism.d3d.D3DContext.validate(D3DContext.java:133)
at com.sun.prism.d3d.D3DContext.validatePresent(D3DContext.java:183)
at com.sun.prism.d3d.D3DRTTexture.readPixels(D3DRTTexture.java:116)
at com.sun.prism.d3d.D3DRTTexture.readPixels(D3DRTTexture.java:90)
at com.sun.javafx.tk.quantum.QuantumToolkit$5.run(QuantumToolkit.java:1437)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.runAndReset(Unknown Source)
at com.sun.javafx.tk.RenderJob.run(RenderJob.java:58)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:125)
at java.lang.Thread.run(Unknown Source)
D3D Vram Pool: 109.314.750 used (20,4%), 159.043.730 target (29,6%), 536.870.912 max
37 total resources being managed
average resource age is 13,1 frames
0 resources at maximum supported age (0,0%)
5 resources marked permanent (13,5%)
0 resources have had mismatched locks (0,0%)
0 resources locked (0,0%)
32 resources contain interesting data (86,5%)
0 resources disappeared (0,0%)
2018-07-17 18:05:09 [JavaFX Application Thread] de.apris3.client.ErrorHandler.handle()
ERROR: : java.lang.IllegalArgumentException: Unrecognized image loader: null
at javafx.scene.image.WritableImage.loadTkImage(WritableImage.java:240)
at javafx.scene.image.WritableImage.access$000(WritableImage.java:46)
at javafx.scene.image.WritableImage$1.loadTkImage(WritableImage.java:51)
at javafx.scene.Scene.doSnapshot(Scene.java:1236)
at javafx.scene.Node.doSnapshot(Node.java:1864)
at javafx.scene.Node.snapshot(Node.java:1942)
...
D3D Vram Pool: 112.230.142 used (20,9%), 159.043.730 target (29,6%), 536.870.912 max
40 total resources being managed
average resource age is 13,0 frames
0 resources at maximum supported age (0,0%)
5 resources marked permanent (12,5%)
0 resources have had mismatched locks (0,0%)
0 resources locked (0,0%)
35 resources contain interesting data (87,5%)
0 resources disappeared (0,0%)
很显然,即使限制足够高,JVM也无法分配足够的内存.搜索 D3D hresult失败:D3D_ERROR ffffffff8007000e
显示实际上是Windows错误( https://docs.microsoft.com/zh-cn/windows/desktop/seccrypto/common-hresult-values ):
Obviously, JVM couldn't allocate enough memory even though the limit was high enough. Searching for D3D hresult failed :D3D_ERROR ffffffff8007000e
revealed it's actually a Windows error (https://docs.microsoft.com/en-us/windows/desktop/seccrypto/common-hresult-values):
E_OUTOFMEMORY Failed to allocate necessary memory 0x8007000E
最后,在检查了设备管理器之后,事实证明客户端已安装了新的图形卡,并且Windows Update更新了驱动程序.
Finally, after checking the device manager, it turned out that the client had installed a new graphic card and Windows Updated screwed the drivers up.
这篇关于如何解决无法识别的图像加载器:JavaFX中为null?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!