最近在處理數據庫導數據的工具,就是迭代發版之前把正式線的工程拷貝到測試環境,執行升級,看看功能是否完善。
所以涉及到對jdbc分頁讀取數據,再存儲到測試環境數據庫。在分頁處理的地方,使用了遞歸。
工具交付給測試同事之後,大部分工程都能拷貝成功,但是有一部分大數據量的工程還是失敗了,最開始的關注點都在數據庫的數據上,因爲比較噁心的是,數據庫存了比較多的二進制字段,超級大文本。失敗的現象是數據導到大表時,都會掛掉,一直跟到掛掉的MySQL記錄,發現數據量並沒有想象中的那麼大。後來在日誌角落裏發現了內存泄漏,好吧,跟數據庫沒關係,一行一行的查代碼。終於看到了遞歸的代碼!
Java中有垃圾回收機制,理論上一個方法執行完了之後,方法內部申請的資源都會被回收,但是遞歸確實不一樣,在整個遞歸結束之後,都不會釋放掉中間申請佔用的資源。我的場景之中,遞歸中查詢到的源數據集合list,很大,當遞歸到一定的程度,必然會掛掉。其實比較簡單的做法就是在遞歸中,對於比較聲明的比較大的對象,直接置null即可,垃圾回收機制會回收這些遞歸中聲明的變量。
即棧中存儲對象的引用以及基本數據類型,堆中存儲對象,引用只想堆中的對象,將引用置null,那麼堆中的對象沒有被引用,那麼堆中申請的資源就會被回收。
直接上代碼: