我希望通过数组对象获得对象缓存
我写了一个测试代码,看看它是如何占用300万个类型对象的内存
它大约是200MB的Ram而且非常好(代码是PersonArray1)
但在我的真实项目中,我的数据是在DB(Mysql)中,必须将它们提取到数组中,所以我编写了一个代码并对其进行测试,但内存使用让我感到困惑!
因为我可以在不放入数据的情况下读取数据,而Ram的使用量大约为23MB,但是当我将它们放入数组时,只需要100,000个索引即可获得300MB的超大内存!!(代码是PersonArray2)
实在我必须有300万个指数
在我现在我的表中有100万行,我认为对于他们所有我需要大约3GB的Ram并且与第一种方式相比它不是很好
起初我认为它是由“ResultSet”或“Statement”对象拍摄的,但事实并非如此!
因为当我把它们放在数据存储器中时,为了看到45的取消注释线和43的备注线
无论如何,我认为我的代码中有一个错误,因为两个相同的数组在逻辑上没有不同,但为什么会发生这种情况以及如何纠正它?
package test;
public class Person {
int province;
int city;
int area;
long phone;
int userType;
int situation;
int score;
int uid;
int priority;
long date;
String content;
public Person(int province, int city, int area, long phone, int userType, int situation, int score, int uid, int priority, long date, String content) {
this.province = province;
this.city = city;
this.area = area;
this.phone = phone;
this.userType = userType;
this.situation = situation;
this.score = score;
this.uid = uid;
this.priority = priority;
this.date = date;
this.content = content;
}
}
package test;
import java.util.Random;
import java.util.Scanner;
public class PersonArray1 {
static Random r = new Random();
public static void main(String[] args) {
long t = System.currentTimeMillis();
Person[] arr = new Person[3000000];
for (int i = 0; i < arr.length; i++) {
arr[i] = new Person(r.nextInt(1000), r.nextInt(1000), r.nextInt(1000), r.nextLong(),
r.nextInt(100), r.nextInt(5), r.nextInt(100), r.nextInt(100), r.nextInt(10000), r.nextLong(),
"Lorem ipsum is a pseudo-Latin text used in web design, typography, layout, "
+ "and printing in place of English to emphasise design elements over content. "
+ "It's also called placeholder (or filler) text. It's a convenient tool for "
+ "mock-ups. It helps to outline the visual elements of a document or presentation,"
+ " eg typography, font, or layout. Lorem ipsum is mostly a part of a Latin text by"
+ " the classical author and philosopher Cicero. Its words and letters have been "
+ "changed by addition or removal, so to deliberately render its content nonsensical;"
+ " it's not genuine, correct, or comprehensible Latin anymore. While lorem ipsum's "
+ "still resembles classical Latin, it actually has no meaning whatsoever. As Cicero's"
+ " text doesn't contain the letters K, W, or Z, alien to latin, these, and others are"
+ " often inserted randomly to mimic the typographic appearence of European languages, "
+ "as are digraphs not to be found in the original.");
}
System.out.println(System.currentTimeMillis() - t);
// using Scanner for dont aloowing to finish process and seeing Ram usage by task manager
Scanner sc = new Scanner(System.in);
sc.next();
}
}
package test;
import java.sql.Connection;
import java.sql.Statement;
import java.util.logging.Level;
import java.util.logging.Logger;
import services.persistence2.DBServicesAutoCommit;
public class CreateTable {
public static void main(String[] args) {
// "DBServicesAutoCommit" is a static Connection Pool
Connection con = DBServicesAutoCommit.getConnection();
try {
Statement ps = con.createStatement();
ps.execute("CREATE TABLE `person`(\n"
+ "`province` INT NOT NULL,\n"
+ "`city` INT,\n"
+ "`area` INT,\n"
+ "`phone` bigint,\n"
+ "`usertype` INT NOT NULL,\n"
+ "`situation` TINYINT NOT NULL,\n"
+ "`score` INT,\n"
+ "`uid` INT NOT NULL,\n"
+ "`priority` INT NOT NULL,\n"
+ "`date` BIGINT NOT NULL,\n"
+ "`content` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL\n"
+ ") ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;");
} catch (Throwable ex) {
Logger.getLogger(CreateTable.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
package test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import services.persistence2.DBServicesManualCommit;
public class FillPersonDB {
static Random r = new Random();
private static String createPersons = "insert into person(province,city,area,phone,usertype,situation,score,uid,priority,date,content)values(?,?,?,?,?,?,?,?,?,?,?)";
public static void createPersons() {
PreparedStatement ps = null;
Connection con = null;
try {
// "DBServicesManualCommit" is a static Connection Pool without auto commit
con = DBServicesManualCommit.getConnection();
ps = con.prepareStatement(createPersons);
// it's take long time but you could to set for 50,000 and fill DB by 20 concurrent connections (multi thread) for just 5 minutes
for (int i = 0; i < 1000000; i++) {
ps.setInt(1, r.nextInt(1000));
ps.setInt(2, r.nextInt(1000));
ps.setInt(3, r.nextInt(1000));
ps.setLong(4, r.nextLong());
ps.setInt(5, r.nextInt(100));
ps.setInt(6, r.nextInt(5));
ps.setInt(7, r.nextInt(100));
ps.setInt(8, r.nextInt(100));
ps.setInt(9, r.nextInt(10000));
ps.setLong(10, r.nextLong());
ps.setString(11, "Lorem ipsum is a pseudo-Latin text used in web design, typography, layout, "
+ "and printing in place of English to emphasise design elements over content. "
+ "It's also called placeholder (or filler) text. It's a convenient tool for "
+ "mock-ups. It helps to outline the visual elements of a document or presentation,"
+ " eg typography, font, or layout. Lorem ipsum is mostly a part of a Latin text by"
+ " the classical author and philosopher Cicero. Its words and letters have been "
+ "changed by addition or removal, so to deliberately render its content nonsensical;"
+ " it's not genuine, correct, or comprehensible Latin anymore. While lorem ipsum's "
+ "still resembles classical Latin, it actually has no meaning whatsoever. As Cicero's"
+ " text doesn't contain the letters K, W, or Z, alien to latin, these, and others are"
+ " often inserted randomly to mimic the typographic appearence of European languages, "
+ "as are digraphs not to be found in the original.");
ps.addBatch();
if (i % 10000 == 0) {
ps.executeBatch();
con.commit();
}
}
ps.executeBatch();
con.commit();
} catch (SQLException ex) {
Logger.getLogger(FillPersonDB.class.getName()).log(Level.SEVERE, null, ex);
} finally {
if (con != null) {
try {
con.close();
} catch (SQLException ex) {
Logger.getLogger(FillPersonDB.class.getName()).log(Level.SEVERE, null, ex);
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException ex) {
Logger.getLogger(FillPersonDB.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}
package test;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
import services.persistence2.DBServicesManualCommit;
public class PersonArray2 {
private static String getPersons = "select * from person limit 100000";
public static void main(String[] args) {
PersonArray2 pa = new PersonArray2();
Person[] person = pa.getPersons();
pa = null;
System.gc();
// using Scanner for dont aloowing to finish process and seeing Ram usage by task manager
Scanner sc = new Scanner(System.in);
sc.next();
}
public Person[] getPersons() {
Statement s = null;
Connection con = null;
ResultSet rs = null;
Person[] person = new Person[1000000];
try {
int c = 0;
long l = System.currentTimeMillis();
con = DBServicesManualCommit.getConnection();
s = con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
s.setFetchSize(Integer.MIN_VALUE);
rs = s.executeQuery(getPersons);
System.out.println("before while");
while (rs.next()) {
// when i dont asign new Person Object to Array ram usage is very low but just asigning Object to array eaten memory a lot
person[c] = new Person(rs.getInt(1), rs.getInt(2), rs.getInt(3), rs.getLong(4), rs.getInt(5), rs.getInt(6), rs.getInt(7), rs.getInt(8), rs.getInt(9), rs.getLong(10), rs.getString(11));
// normal memory usage without putting into array
//new Person(rs.getInt(1), rs.getInt(2), rs.getInt(3), rs.getLong(4), rs.getInt(5), rs.getInt(6), rs.getInt(7), rs.getInt(8), rs.getInt(9), rs.getLong(10), rs.getString(11));
if (c++ % 10000 == 0) {
System.out.println("Current Index is :"+(c-1));
}
}
System.out.println(System.currentTimeMillis() - l);
System.out.println(person.length + "|" + person[99999].phone);
return person;
} catch (SQLException ex) {
Logger.getLogger(PersonArray2.class.getName()).log(Level.SEVERE, null, ex);
return null;
} finally {
if (rs != null) {
try {
rs.close();
rs = null;
} catch (SQLException ex) {
Logger.getLogger(PersonArray2.class.getName()).log(Level.SEVERE, null, ex);
}
}
if (s != null) {
try {
s.close();
s = null;
} catch (SQLException ex) {
Logger.getLogger(PersonArray2.class.getName()).log(Level.SEVERE, null, ex);
}
}
if (con != null) {
try {
con.close();
con = null;
} catch (SQLException ex) {
Logger.getLogger(PersonArray2.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}