缺陷樣本
示例代碼一
在下面Java方法中,創建I/O流對象後未進行合理釋放,程式依靠Java虛擬機的垃圾回收機制釋放I/O流資源,事實上,程式不能確定何時調用虛擬機的finalize()方法。在繁忙的程式環境下,可能導致Java虛擬機不能有效的使用I/O對象。
public void processFile(String filePath){ try { FileInputStreamfis = new FileInputStream(filePath); InputStreamReader isr = new InputStreamReader(fis); BufferedReaderbr = new BufferedReader(isr); String line=""; while((line=br.readLine())!=null){ processLine(line); } }catch (FileNotFoundException e) { log(e); }catch (IOException e){ log(e); } }
public void processFile(String filePath){
try {
FileInputStreamfis = new FileInputStream(filePath);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReaderbr = new BufferedReader(isr);
String line="";
while((line=br.readLine())!=null){
processLine(line);
}
}catch (FileNotFoundException e) {
log(e);
}catch (IOException e){
log(e);
}
}
示例修復建議:
應在finally塊中釋放I/O對象。
public void processFile(String filePath){ FileInputStreamfis = null; InputStreamReaderisr = null; BufferedReaderbr = null; try{ fis= new FileInputStream(filePath); isr = new InputStreamReader(fis); br= new BufferedReader(isr); Stringline=""; while((line=br.readLine())!=null){ //processLine(line); } }catch (FileNotFoundException e) { //log(e); }catch (IOException e){ //log(e); }finally{ if(br!=null){ try{br.close(); }catch (IOException e) {//log(e); } } if(isr!=null){ try{isr.close(); }catch (IOException e) {//log(e); } } if(fis!=null){ try{fis.close(); }catch (IOException e) {//log(e); } } } }
public void processFile(String filePath){
FileInputStreamfis = null;
InputStreamReaderisr = null;
BufferedReaderbr = null;
try{
fis= new FileInputStream(filePath);
isr = new InputStreamReader(fis);
br= new BufferedReader(isr);
Stringline="";
while((line=br.readLine())!=null){
//processLine(line);
}
}catch (FileNotFoundException e) {
//log(e);
}catch (IOException e){
//log(e);
}finally{
if(br!=null){
try{
br.close();
}catch (IOException e) {
//log(e);
}
}
if(isr!=null){
try{
isr.close();
}catch (IOException e) {
//log(e);
}
}
if(fis!=null){
try{
fis.close();
}catch (IOException e) {
//log(e);
}
}
}
}
示例代碼二
在下面Java代碼片段中,創建資料庫對象資源後未進行合理釋放,在繁忙的程式環境下,資料庫連線池可能會耗盡,從而導致其他用戶不能訪問該資料庫資源。
try { Connection conn = DriverManager.getConnection(some_connection_string) PreparedStatementstmt = conn.prepareStatement(sqlquery); ……} catch (Exceptione) { log(e);}
try {
Connection conn = DriverManager.getConnection(some_connection_string)
PreparedStatementstmt = conn.prepareStatement(sqlquery);
……
} catch (Exceptione) {
log(e);
}
示例修復建議:
應在finally塊中釋放資料庫資源。
Connection conn=null; PreparedStatement stmt=null; try{ conn = DriverManager.getConnection(some_connection_string); stmt = conn.prepareStatement(sqlquery); …… } catch(SQLExceptione){ log(e); }finally{ if(con!=null){ try{conn.close(); } catch (SQLException e) {log(e); } } if(stmt!=null){ try {stmt.close(); } catch (SQLException e) {log(e); } } }
Connection conn=null;
PreparedStatement stmt=null;
try{
conn = DriverManager.getConnection(some_connection_string);
stmt = conn.prepareStatement(sqlquery);
……
} catch(SQLExceptione){
log(e);
}finally{
if(con!=null){
try{
conn.close();
} catch (SQLException e) {
log(e);
}
}
if(stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
log(e);
}
}
}
防護措施
程式創建或分配資源後,應進行合理的釋放。在Java開發中,I/O流資源、資料庫資源應該在finally語句塊中進行合理釋放。