forum.bitel.ru http://forum.bitel.ru/ |
|
java.lang.OutOfMemoryError http://forum.bitel.ru/viewtopic.php?f=19&t=5533 |
Страница 1 из 1 |
Автор: | aiwbend [ 26 май 2011, 18:02 ] |
Заголовок сообщения: | java.lang.OutOfMemoryError |
Доброго времени суток. Есть скрипт который импортирует кучу договоров из csv таблицы. При его выполнении постепенно падает скорость импорта и примерно на 2000 договоре биллинг не может создать договор и выдает "java.lang.OutOfMemoryError: Java heap space." в логах. Выставлял -Xmx1024m не помогло. прошу совета, не очень хочется скрипт по сто раз запускать. |
Автор: | Cromeshnic [ 26 май 2011, 18:06 ] |
Заголовок сообщения: | Re: java.lang.OutOfMemoryError |
Настучать по голове тому, кто делал скрипт, чтобы переделали без утечек памяти. |
Автор: | aiwbend [ 27 май 2011, 09:21 ] |
Заголовок сообщения: | Re: java.lang.OutOfMemoryError |
не нужно по голове В общем сил уже нет, вынесли все из цикла что увидели. мб Java гуру не вооружённым глазом определят где происходит утечка. Код прилагаю. Заранее спасибо. Код: import bitel.billing.server.admin.bean.*;
import bitel.billing.server.util.*; import com.Ostermiller.util.*; import java.util.*; import bitel.billing.common.*; import java.io.*; import java.sql.*; import bitel.billing.server.contract.bean.*; import bitel.billing.server.contract.*; import ru.bitel.common.*; import java.math.*; import java.util.regex.*; import java.text.*; int LOADED_GROUP = 7; int PATTERN_ID = 7; int PAYMENT_TYPE_ID = 1; int CHARGE_TYPE_ID = 7; int CITY_ID = 1; int ADDRESS_PARAM_ID = 13; int PHONE_PARAM_ID = 4; int DATAZAKLUCH_PARAM_ID = 6; int DATAPODKLUCH_PARAM_ID = 20; int FIO_PARAM_ID = 2; int DOC_PARAM_ID = 17; int LGOTA_PARAM_ID = 19; int PRIMECHANIE_PARAM_ID = 18; int KREDIT_PARAM_ID = 25; java.util.Date curdate = new java.util.Date(); java.util.Date beginmonth = new java.util.Date(curdate.getYear(),curdate.getMonth(),1); Calendar now = new GregorianCalendar(); DecimalFormat format5 = new DecimalFormat( "00000" ); Map streetMap; Map houseMap; public void main( setup, con, conSlave ) { long timeStart = System.currentTimeMillis(); loadFile( "C:/3.csv", setup, con, 11 ); long timeEnd = System.currentTimeMillis(); print( "Process time: " + (timeEnd - timeStart)/1000 + " s." ); } private void loadFile( file, setup, con, patternId ) { int rowNum = 0; print( "Loading " + file ); String query; ContractManager cm = new ContractManager( con ); ContractTariffManager ctm = new ContractTariffManager( con ); ContractParameterManager cpm = new ContractParameterManager( con ); PaymentManager paymentManager = new PaymentManager( con ); ChargeManager chargeManager = new ChargeManager( con ); BalanceUtils bu = new BalanceUtils( con ); query = "INSERT INTO contract_balance(yy, mm, cid, summa1) VALUES(?,?,?,?)"; PreparedStatement psInsertBalance = con.prepareStatement( query ); psInsertBalance.setInt( 1, now.get( Calendar.YEAR ) ); psInsertBalance.setInt( 2, now.get( Calendar.MONTH ) + 1 ); String[][] data = ExcelCSVParser.parse( new InputStreamReader( new FileInputStream( file ), "windows-1251" ) , ';' ); if( data != null && data.length > 0 ) { final int rowCount = data.length; if( streetMap == null ) { streetMap = new HashMap(); query = "SELECT id, title FROM address_street WHERE cityid=1"; PreparedStatement ps = con.prepareStatement( query ); ResultSet rs = ps.executeQuery(); while( rs.next() ) { streetMap.put( rs.getString( 2 ), rs.getInt( 1 ) ); //print( "Loaded street: " + rs.getString( 2 ) + " => " + rs.getString( 1 ) ); } ps.close(); } if( houseMap == null ) { houseMap = new HashMap(); query = "SELECT streetid, house, frac, id FROM address_house"; PreparedStatement ps = con.prepareStatement( query ); ResultSet rs = ps.executeQuery(); while( rs.next() ) { String key = rs.getString( 1 ) + "-" + rs.getString( 2 ) + rs.getString( 3 ); houseMap.put( key, rs.getInt( 4 ) ); //print( "Loaded house: " + key + " => " + id ); } ps.close(); } String licSchet; String datazakluch; String datapodkl; String addressstreet; String addresshome; String addresskorp; String addressroom; String fio; String dokument; String phone; String stoimostpodkl; String lgota; String tariff; String primechanie; String ostatokkredit; BigDecimal saldo = BigDecimal.ZERO; BigDecimal pay = BigDecimal.ZERO; BigDecimal charge = BigDecimal.ZERO; String pswd; String title; Integer streetId; String houseKey; Integer houseId; Contract contract; String[] fields; //запускает цикл импортирования договоров for( rowNum = 1; rowNum < rowCount; rowNum++ ) { fields = new String[40]; fields = data[rowNum]; //print ("rowNum" + data[rowNum]); if( fields.length < 9 ){error( "Incorrect line " + rowNum ); continue;} if( rowNum % 100 == 0 ){System.out.println( "Count => " + rowNum );} licSchet = fields[0]; datazakluch = fields[1]; datapodkl = fields[2]; addressstreet = fields[3]; addresshome = fields[4]; addresskorp = fields[5]; addressroom = fields[6]; fio = fields[7]; dokument = fields[10]; phone = fields[11]; stoimostpodkl = fields[12]; lgota = fields[13]; tariff = fields[14]; primechanie = fields[15]; ostatokkredit = fields[16]; saldo = BigDecimal.ZERO; //print (addressstreet + addresshome + addresskorp + addressroom); try { saldo = new BigDecimal( fields[17].replaceAll( " ", "0" ) ); //pay = new BigDecimal( fields[0].replaceAll( " ", "0" ) ); //charge = new BigDecimal( fields[0].replaceAll( " ", "0" ) ); } catch( Exception ex ) { error( "Error load summ file: " + file + "; line: " + rowNum + "; fio: " + fio ); } //print( "FIO:" + fio + "; licChet: " + licSchet + "; tariff:" + tariff ); pswd = PswdGen.generatePassword( 5, "0123456789" ); title = "СКПТ-" + format5.format( Utils.parseLong( licSchet ) ); // создание договора contract = cm.createFromPattern( patternId, title, TimeUtils.convertDateToCalendar( beginmonth ), pswd ); //Выбираем руппу contract.setGroups( contract.getGroups() | (1L<<7) ); contract.setComment( fio ); cm.updateContract( contract ); streetId = streetMap.get( addressstreet ); if( streetId == null ) { query = "INSERT INTO address_street(cityid, title) VALUES(?, ?)"; PreparedStatement ps = con.prepareStatement( query, PreparedStatement.RETURN_GENERATED_KEYS ); ps.setInt( 1, CITY_ID ); ps.setString( 2, addressstreet ); ps.executeUpdate(); streetId = ServerUtils.lastInsertId( ps ); streetMap.put( addressstreet, streetId ); ps.close(); } houseKey = streetId + "-" + addresshome + addresskorp; houseId = houseMap.get( houseKey ); if( houseId == null ) { query = "INSERT INTO address_house(streetid, house, frac) VALUES(?,?,?)"; PreparedStatement ps = con.prepareStatement( query, PreparedStatement.RETURN_GENERATED_KEYS ); ps.setInt( 1, streetId ); ps.setString( 2, addresshome ); ps.setString( 3, addresskorp ); ps.executeUpdate(); houseId = ServerUtils.lastInsertId( ps ); houseMap.put( houseKey, houseId ); ps.close(); } ContractAddressParamValue addressParam = new ContractAddressParamValue(); addressParam.setHouseId( houseId ); addressParam.setFlat( addressroom ); addressParam.setRoom( "" ); addressParam.setFloor( -1 ); addressParam.setPod( -1 ); addressParam.setAddress("ул. " + addressstreet + ", д. " + addresshome + ", кв. " + addressroom ); addressParam.setComment( "" ); cpm.setAddressParam( contract.getId(), ADDRESS_PARAM_ID, addressParam, User.USER_SERVER ); if( Utils.notBlankString( phone ) ){cpm.setStringParam( contract.getId(), PHONE_PARAM_ID, phone, User.USER_SERVER );} if( Utils.notBlankString( dokument ) ){cpm.setStringParam( contract.getId(), DOC_PARAM_ID, dokument, User.USER_SERVER );} if( Utils.notBlankString( lgota ) ){cpm.setStringParam( contract.getId(), LGOTA_PARAM_ID, lgota, User.USER_SERVER );} // if( Utils.notBlankString( datazakluch ) ){cpm.setStringParam( contract.getId(), DATAZAKLUCH_PARAM_ID, datazakluch, User.USER_SERVER );} if( Utils.notBlankString( datapodkl ) ){cpm.setStringParam( contract.getId(), DATAPODKLUCH_PARAM_ID, datapodkl, User.USER_SERVER );} if( Utils.notBlankString( primechanie ) ){cpm.setStringParam( contract.getId(), PRIMECHANIE_PARAM_ID, primechanie, User.USER_SERVER );} if( Utils.notBlankString( stoimostpodkl ) ){cpm.setStringParam( contract.getId(), KREDIT_PARAM_ID, " Стоимость подкл.:" + stoimostpodkl + "р." + " Остаток за кредит:" + ostatokkredit + "р.", User.USER_SERVER );} // баланс if( saldo.compareTo( BigDecimal.ZERO ) != 0 ) { psInsertBalance.setInt( 3, contract.getId() ); psInsertBalance.setBigDecimal( 4, saldo ); psInsertBalance.executeUpdate(); } cpm.setStringParam( contract.getId(), FIO_PARAM_ID, fio, User.USER_SERVER ); bu.updateBalance( curdate, contract.getId() ); // установка тарифа ContractTariff contractTariff = new ContractTariff(); contractTariff.setContractID( contract.getID() ); switch(tariff) { case "200": contractTariff.setTariffPlanID( 168 ); break; case "165": contractTariff.setTariffPlanID( 170 ); break; case "250": contractTariff.setTariffPlanID( 171 ); break; case "260": contractTariff.setTariffPlanID( 172 ); break; case "45": contractTariff.setTariffPlanID( 173 ); break; case "330": contractTariff.setTariffPlanID( 174 ); break; case "84": contractTariff.setTariffPlanID( 175 ); break; } contractTariff.setComment( "" ); contractTariff.setDate1( TimeUtils.convertDateToCalendar( curdate ) ); ctm.updateContractTariff( contractTariff ); } } } |
Автор: | Администратор [ 27 май 2011, 09:49 ] |
Заголовок сообщения: | Re: java.lang.OutOfMemoryError |
Проблема, вероятнее всего, в PoolableConnection. У него есть особенность - держать результаты запроса до тех пор пока коннекшен, ResultSet либо PreparedStatement не будет закрыт (возвращён в пул). Может где-то сами ps не закрыли, а может где-то в API нашем. Т.к. приложение временное, то самый простой "путь в лоб" - через каждые сколько-то итераций возвращать коннект в пул и получать новый. ServerUtils.closeConnection(con); con = setup.getDbConnectionFromPool(); Ну и все менеджеры пересоздавать придётся. |
Автор: | skyb [ 27 май 2011, 10:06 ] |
Заголовок сообщения: | Re: java.lang.OutOfMemoryError |
aiwbend писал(а): не нужно по голове Я даже предполагаю кто его писал ![]() |
Автор: | aiwbend [ 27 май 2011, 15:50 ] |
Заголовок сообщения: | Re: java.lang.OutOfMemoryError |
Администратор писал(а): Т.к. приложение временное, то самый простой "путь в лоб" - через каждые сколько-то итераций возвращать коннект в пул и получать новый. ServerUtils.closeConnection(con); con = setup.getDbConnectionFromPool(); Ну и все менеджеры пересоздавать придётся. Сделал так. Код: if( rowNum % 10 == 0 ) { ServerUtils closeConnection(con); con = setup.getDbConnectionFromPool(); ContractManager cm = new ContractManager( con ); ContractTariffManager ctm = new ContractTariffManager( con ); ContractParameterManager cpm = new ContractParameterManager( con ); PaymentManager paymentManager = new PaymentManager( con ); ChargeManager chargeManager = new ChargeManager( con ); BalanceUtils bu = new BalanceUtils( con ); } ServerUtils closeConnection(con); с точкой не работало(хотя и сейчас может не останавливает ![]() Цитата: Error in method invocation: Static method closeConnection( org.apache.commons.dbcp.PoolableConnection ) not found in class'ru.bitel.bgbilling.server.util.ServerUtils' : at Line: 140 : in file: test import : ServerUtils .closeConnection ( con ) теперь ругается на con = setup.getDbConnectionFromPool(); Цитата: Error in method invocation: Method getDbConnectionFromPool() not found in class'ru.bitel.bgbilling.server.util.Setup' : at Line: 141 : in file: test import : setup .getDbConnectionFromPool ( ) есть мысли? ![]() |
Автор: | stark [ 27 май 2011, 16:33 ] |
Заголовок сообщения: | Re: java.lang.OutOfMemoryError |
aiwbend писал(а): ServerUtils closeConnection(con); с точкой не работало(хотя и сейчас может не останавливает ![]() Цитата: Как это не работало ? на что ругалось ? Без точки это бред |
Автор: | aiwbend [ 27 май 2011, 16:49 ] |
Заголовок сообщения: | Re: java.lang.OutOfMemoryError |
stark писал(а): aiwbend писал(а): ServerUtils closeConnection(con); с точкой не работало(хотя и сейчас может не останавливает ![]() Цитата: Как это не работало ? на что ругалось ? Без точки это бред aiwbend писал(а): Error in method invocation: Static method closeConnection( org.apache.commons.dbcp.PoolableConnection ) not found in class'ru.bitel.bgbilling.server.util.ServerUtils' : at Line: 140 : in file: test import : ServerUtils .closeConnection ( con )
|
Автор: | stark [ 27 май 2011, 16:54 ] |
Заголовок сообщения: | Re: java.lang.OutOfMemoryError |
aiwbend писал(а): stark писал(а): aiwbend писал(а): ServerUtils closeConnection(con); с точкой не работало(хотя и сейчас может не останавливает ![]() Цитата: Как это не работало ? на что ругалось ? Без точки это бред aiwbend писал(а): Error in method invocation: Static method closeConnection( org.apache.commons.dbcp.PoolableConnection ) not found in class'ru.bitel.bgbilling.server.util.ServerUtils' : at Line: 140 : in file: test import : ServerUtils .closeConnection ( con ) У вас между ServerUtils и .closeConnection ( con ) не стоит пробел случайно? |
Автор: | aiwbend [ 27 май 2011, 17:29 ] |
Заголовок сообщения: | Re: java.lang.OutOfMemoryError |
stark писал(а): У вас между ServerUtils и .closeConnection ( con ) не стоит пробел случайно? Тоже в глаза бросилось когда оформлял пост. В скрипте пробела нет, все слитно, в логах он есть) Думаю уже сделать чтобы по очереди скрипты запускались по 1000 договоров на скрипт ![]() |
Автор: | snark [ 29 май 2011, 17:27 ] |
Заголовок сообщения: | Re: java.lang.OutOfMemoryError |
aiwbend писал(а): Есть скрипт который импортирует кучу договоров из csv таблицы. MySQL LOAD DATA INFILE MySQL писал(а): The LOAD DATA INFILE statement reads rows from a text file into a table at a very high speed. И потом в скрипте обрабатывать уже загруженные данные, если такая обработка понадобится. |
Автор: | RimiX [ 03 ноя 2011, 09:43 ] |
Заголовок сообщения: | Re: java.lang.OutOfMemoryError |
Сабж один и тот же поэтому напишу здесь. У нас возникает периодически. Хотя в server.ini выставлено 1024. И зачем вообще в скрипте запуска стоит 256 , и на кой тогда нужен server.ini? Я хотел бы увеличить памяти для ява процесса. Мне надо в скрипте запуска изменить, и параметр в server.ini вообще не то? |
Автор: | stark [ 11 ноя 2011, 17:03 ] |
Заголовок сообщения: | Re: java.lang.OutOfMemoryError |
RimiX писал(а): Сабж один и тот же поэтому напишу здесь. У нас возникает периодически. Хотя в server.ini выставлено 1024. И зачем вообще в скрипте запуска стоит 256 , и на кой тогда нужен server.ini? Я хотел бы увеличить памяти для ява процесса. Мне надо в скрипте запуска изменить, и параметр в server.ini вообще не то? вы вообще про что ? тут писали про сервер, а вы похоже про сервер биллинга. Создайте отдельную тему |
Автор: | dimOn [ 14 ноя 2011, 11:32 ] |
Заголовок сообщения: | Re: java.lang.OutOfMemoryError |
RimiX писал(а): Сабж один и тот же поэтому напишу здесь. У нас возникает периодически. Хотя в server.ini выставлено 1024. И зачем вообще в скрипте запуска стоит 256 , и на кой тогда нужен server.ini? Я хотел бы увеличить памяти для ява процесса. Мне надо в скрипте запуска изменить, и параметр в server.ini вообще не то? в скрипте запуска для запуска скриптом запуска, в server.ini для запуска виндовым сервайс-запускателем |
Страница 1 из 1 | Часовой пояс: UTC + 5 часов [ Летнее время ] |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |