2015-01-21 2 views
-1

Привет Я столкнулся с проблемой с вставкой 1lac-данных в таблицу с двумя столбцами (Id & Id). Может кто-нибудь оптимизировать код.Исключение из памяти для более чем 1 lac-данных

public class edgeConnection { 
static ArrayList al3 = new ArrayList(); 
static HashSet set=null; 
//static HashMap hm = null; 
//static int val ; 
//Database connection 
public static DataSource getMySQLDataSource() throws Exception { 
    Properties props = new Properties(); 
    FileInputStream fis = null; 
    MysqlDataSource mysqlDS = null; 

    try { 
     fis = new FileInputStream("D:/Assignments/Sequence/db.properties"); 
    } catch (FileNotFoundException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    props.load(fis); 
    mysqlDS = new MysqlDataSource(); 
    mysqlDS.setURL(props.getProperty("MYSQL_DB_URL")); 
    mysqlDS.setUser(props.getProperty("MYSQL_DB_USERNAME")); 
    mysqlDS.setPassword(props.getProperty("MYSQL_DB_PASSWORD")); 
    return mysqlDS; 
} 

//Adding values to Hashset 
private static int addNode(){ 
    set = new HashSet(); 
    for(int i=1;i<=10000;i++){/*Change 10000 to 30000*/ 
     set.add(i); 
    } 
    return 0; 
} 
private static int keyNode(int i){ 
    int counter = 1; 
    Iterator it = set.iterator(); 
    while(it.hasNext()) 
    { 
     int value = (int) it.next(); 
     if(i==counter) 
     { 
      //System.out.println("key value returned ::"+value); 
      return value; 
     } 
     counter++; 
    } 
    return 0; 
} 
private static String pairGenerator(){ 
    ArrayList numbers1 = new ArrayList<Integer>(); 
    Random randomGenerator1 = new Random(); 
    while (numbers1.size() < 1) 
    { 
     int random = randomGenerator1 .nextInt(15); 
     if (!numbers1.contains(random)) { 
      numbers1.add(random); 
     } 
    } 
    Iterator it1 = numbers1.iterator(); 
    while(it1.hasNext()){ 
     return(String.valueOf(it1.next())); 
    } 
    return null; 
} 

private static List valueNodes(){ 
    //Generate no randomly. 
    ArrayList<Integer> numbers = new ArrayList<Integer>(); 
    Random randomGenerator = new Random(); 
    String size = pairGenerator(); 
    int size1= Integer.parseInt(size)+1; 
    //System.out.println("the size1 is ::"+size1); 
    while (numbers.size() < size1) 
    { 
     int random = randomGenerator .nextInt(10000);/*Change 10000 to 50000*/ 
     if (!numbers.contains(random)) { 
      numbers.add(random); 
     } 
    } 
    Iterator it = numbers.iterator(); 
    al3.clear(); 

    while(it.hasNext()){ 
     int listvalue = (int) it.next(); 
     al3.add(listvalue); 

     //System.out.println(it.next()); 
    } 
    //System.out.println(al3); 
    return al3; 
} 
public static void main(String[] args) throws Exception { 
    Connection con = null; 
    PreparedStatement pst = null; 
    ResultSet rs = null; 
    HashMap<Integer, List<String>> hm = new HashMap<Integer, List<String>>(); 
    addNode(); 
    //System.out.println("size of set is:"+set.size()); 
    try { 
     con = getMySQLDataSource().getConnection(); 
     List<Integer> valueList = new ArrayList<Integer>(); 
     int nodeId; 
     for(int i=1;i<=set.size();i++) 
     { 
      hm.put(keyNode(i), valueNodes()); 
      Iterator iter = hm.entrySet().iterator(); 
      while(iter.hasNext()) 
      { 
       Map.Entry entry = (Map.Entry) iter.next(); 
       System.out.println(entry.getKey()+"<-->"+" "+entry.getValue()); 
       nodeId = (int) entry.getKey(); 
       valueList = (List<Integer>) entry.getValue(); 
       //System.out.println("size of value list : "+valueList.size()); 
       for(int j = 0;j<valueList.size();j++) 
       { 
        pst = con.prepareStatement("insert into nodes_connection values (?,?)"); 
        pst.setInt(1, nodeId); 
        if(valueList.get(j)!=0) 
        { 
         pst.setInt(2,valueList.get(j)); 
        } 
        else{ 
         int updatedValue = valueList.get(j)+10000;/*Change 10000 to 30000*/ 
         pst.setInt(2,updatedValue); 
        } 
        pst.executeUpdate(); 
        //System.out.println(j+"record updated.."); 
       } 
       iter.remove(); 
      } 
     } 
     System.out.println("Record successfully added"); 
    } catch (SQLException e) { 
     e.printStackTrace(); 
    }finally{ 
     try { 
      if(rs != null) rs.close(); 
      if(pst != null) pst.close(); 
      if(con != null) con.close(); 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     } 
    } 


}` 

Мне нужно удалить arraylist и hashmap. Как я могу оптимизировать код, чтобы я не получал исключение из памяти кучи java.

+0

Вам действительно нужно сначала построить эту огромную структуру в памяти? Не можете ли вы рассчитать его по очереди? – Thilo

ответ

0

Поскольку вы вставляете столько строк, вы должны использовать пакетное обновление вместо вставки одной строки за раз.

PreparedStatement pst = con.prepareStatement("insert into nodes_connection values (?,?)"); 
for(int i=1;i<=set.size();i++) 
    { 
     hm.put(keyNode(i), valueNodes()); 
     Iterator iter = hm.entrySet().iterator(); 
     while(iter.hasNext()) 
     { 
      Map.Entry entry = (Map.Entry) iter.next(); 
      System.out.println(entry.getKey()+"<-->"+" "+entry.getValue()); 
      nodeId = (int) entry.getKey(); 
      valueList = (List<Integer>) entry.getValue(); 
      //System.out.println("size of value list : "+valueList.size()); 
      for(int j = 0;j<valueList.size();j++) 
      { 

       pst.setInt(1, nodeId); 
       if(valueList.get(j)!=0) 
       { 
        pst.setInt(2,valueList.get(j)); 
       } 
       else{ 
        int updatedValue = valueList.get(j)+10000;/*Change 10000 to 30000*/ 
        pst.setInt(2,updatedValue); 
       } 
       pst.addBatch() 
       //System.out.println(j+"record updated.."); 
      } 
      iter.remove(); 
     } 
    } 


    pst.executeBatch() 

Вы можете пойти here для получения дополнительной информации о пакетных вставках.

+0

Звучит так, что будет использовать еще больше памяти. – Thilo

0

К несчастью, самое легкое для вас дело - просто increase the heap size.

Если это то, что вы собираетесь запускать только один раз или играете вокруг, в основном все, что не является критическим для производства, или обработает ОГРОМНОЕ количество данных, то увеличение кучи даст вам то, что вы хотите.

Если вам нужно оставить снимок памяти, вам нужно будет передавать данные вместо чтения всего этого в память. Глядя на ваш код, кажется, каждая строка данных не имеет никакого отношения к остальной части данных в файле, так и в псевдо-коде образом, что-то вроде следующего будет работать:

For each line in file 
    Calculate data to be inserted into database 
    Update database 

Вы можете повысить эффективность более вместо того, чтобы обновлять базу данных для каждой строки, делая это в пакете, что изменило бы ваше псевдо:

For each line in file 
    Calculate data to be inserted into database 
    Add update to a JDBC batch 
    If batch size > :somelimit 
     execute batch 
Execute final batch 
Смежные вопросы