Stacktraces告诉了事实。 但事实并非如此。
我們公司致力于使軟件錯誤的原因對開發人員和運營透明。 與替代解決方案相反, 我們將問題的位置浮出水面,使您指向源代碼中的惡意行。 即使我們目前以檢測內存泄漏的能力而聞名,但我們也正在擴展到其他領域。 為了給您一些有關我們研究方向的提示,我們決定通過三個示例進行分享。
這些示例歸結為JVM功能,以提供有意義的堆棧跟蹤。 在許多情況下,stacktrace確實包含解決問題所需的所有信息。 在其他情況下,它只是浮??出水面,不知道可能是什么引起了潛在的問題。 讓我用觸發以下臭名昭著的錯誤消息的三個示例進行說明:
- java.lang.OutOfMemoryError:無法創建新的本機線程
- java.io.IOException:系統中打開的文件過多
- java.lang.OutOfMemoryError:Java堆空間
所有示例都使用簡單的代碼片段進行了說明,從而使潛在問題更易于理解。
線程太多
static void createTooManyThreads() {try {for (int i = 0; i < TOO_MANY; i++) {Thread t = new Thread(new Runnable() {public void run() {try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}}});t.start();}} catch (OutOfMemoryError e) {e.printStackTrace();} }在上面的代碼中,我們一直在啟動線程,直到達到系統限制并遇到“ java.lang.OutOfMemoryError:無法創建新的本機線程”消息。 理解問題與線程限制耗盡有關,這有什么問題? 讓我們仔細看看stacktrace:
java.lang.OutOfMemoryError: unable to create new native threadat java.lang.Thread.start0(Native Method)at java.lang.Thread.start(Thread.java:693)at eu.plumbr.demo.MisleadingStacktrace.createTooManyThreads(MisleadingStacktrace.java:34)at eu.plumbr.demo.MisleadingStacktrace.main(MisleadingStacktrace.java:16)問題就一直盯著我們的臉-有人告訴我們添加最后一根稻草將駝背弄斷了。 同時,我們沒有一個線索是,駱駝已經被完全裝載了。 如果錯誤消息還包含一種方法,以查看在我們最后一次嘗試啟動最后一個調用導致上述堆棧跟蹤之前,哪個調用堆棧正在消耗線程的不同跟蹤,那么它將使開發人員的工作變得更加輕松。
但是讓我們看一下相同的問題–從另一個角度來看資源消耗:
打開的文件太多
再次,讓我們從示例代碼開始:
static void createTooManyFiles() {try {for (int i = 0; i < TOO_MANY; i++) {File f = new File(PATH_TO_FILE + i + ".txt");f.createNewFile();OutputStream s = new FileOutputStream(f);s.write(1);}} catch (IOException e) {e.printStackTrace();} }該示例嘗試創建許多文件,并且僅在每個文件中寫入一個整數而不關閉先前的文件。 再一次,運行上面的代碼會導致堆棧跟蹤不太有用:
java.io.IOException: Too many open files in systemat java.io.UnixFileSystem.createFileExclusively(Native Method)at java.io.File.createNewFile(File.java:947)at eu.plumbr.demo.MisleadingStacktrace.createTooManyFiles(MisleadingStacktrace.java:45)at eu.plumbr.demo.MisleadingStacktrace.main(MisleadingStacktrace.java:17)現在,以不同的方式掩蓋了相同的問題-我們確實得到了這樣的消息:我現在嘗試過多地打開一個文件,但是-誰打開了另一個文件來向JVM施加壓力,使其無法完成運行?
如果您仍然不確定,請看第三個示例,即我們目前的面包和黃油:
消耗太多內存
代碼示例再次很簡單–我們采用數據結構并不斷增加結構,直到可用堆耗盡為止:
static void createTooLargeDataStructure() {try {List l = new ArrayList();for (int i = 0; i < TOO_MANY; i++) {l.add(i);}} catch (OutOfMemoryError e) {e.printStackTrace();} }運行代碼會給您帶來臭名昭著的java.lang.OutOfMemoryError:Java堆空間消息。 如果所討論的數據結構是通過源代碼中的不同可能位置來填充的,那么這又很難解釋。
我知道所有C語言開發人員現在都無奈地聳了聳肩,因為在他們的世界中,以上所有內容都只是采取段錯誤的形式,但是–如果我們走得那么遠,為什么我們不能做得更好? 我相信我們可以做到,那就是我們將要做的–為您找到性能瓶頸 。
 如果您對完整的代碼示例感興趣,可以在此處下載。 該代碼在JDK 7u25上的OS X 10.9的Macbook Pro上運行。 之后,請確保您不會錯過未來有趣內容的更新,并訂閱我們的Twitter feed 。 
翻譯自: https://www.javacodegeeks.com/2013/11/stacktraces-are-telling-the-truth-but-not-the-whole-truth.html
總結
以上是生活随笔為你收集整理的Stacktraces告诉了事实。 但事实并非如此。的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 使用Apache Mahout创建在线推
- 下一篇: 租房备案表是什么(租房备案表)
