我们有一个java应用程序,我可以说它也使用了很多字符串变量。此外,我们启动它,最大和初始内存设置为256Mb。此后它运行了一段时间,直到最近我们发现它首先是一个GC,并在将近2周之后再发现一个GC。因此我们发现FC的平均值为0.2145s,YGC为0.0511s。我们不确定这些值是合适的还是导致其他的?我们决定将内存增加到512Mb并查看其他一些GC设置,例如CMS设置?还应优化代码,如String变量的使用?通常什么是对象或变量类型将移动到旧对象?
Timestamp S0 S1 E O P YGC YGCT FGC FGCT GCT
2752472.6 69.74 0.00 3.67 51.72 44.17 4614 235.630 2 0.429 236.059
2752477.6 69.74 0.00 5.38 51.72 44.17 4614 235.630 2 0.429 236.059
2752482.6 69.74 0.00 7.51 51.72 44.17 4614 235.630 2 0.429 236.059
2752487.6 69.74 0.00 9.52 51.72 44.17 4614 235.630 2 0.429 236.059
2752492.6 69.74 0.00 10.55 51.72 44.17 4614 235.630 2 0.429 236.059
代码段
BoneCP connectionPool = null;
class ConnectionHandler implements Runnable {
private Socket receivedSocketConn1;
ConnectionHandler(Socket receivedSocketConn1) {
this.receivedSocketConn1=receivedSocketConn1;
}
Connection dbconn = null;
public void run() { // etc
BufferedWriter writeBuffer = null;
BufferedReader readBuffer = null;
String capturedMessage="";
try{
dbconn = connectionPool.getConnection();
dbconn.setAutoCommit(false);
while ((nextChar=readBuffer.read()) != -1){
capturedMessage += (char) nextChar;
if (nextChar == '*')
{
try{
//all queries here.
//for insert query this how i do
Statement stmt1 = null;
stmt1 = dbconn.createStatement();
String insertQuery3 =........
count = stmt9.executeUpdate(insertQuery3);
try{
if ( stmt1!= null ){ stmt1.close();
}
else{
System.out.println("No stm1 exist");
}
}catch(SQLException ex){
System.out.println("SQLException has been caught for stmt1");
ex.printStackTrace(System.out);
}
///For select we do this
Statement stmt2 = null;
stmt2 = dbconn.createStatement();
String selectQuery2= .........
ResultSet rs2 = stmt2.executeQuery(selectQuery2);
if(rs2.next())
{
}
try{
if ( rs2!= null ){
rs2.close();
} else{
System.out.println("No rs2 exist");
}
if ( stmt2!= null ){
stmt2.close();
} else{
System.out.println("No stm2 exist");
}
}catch(SQLException ex)
{
System.out.println("SQLException has been caught for stmt2");
ex.printStackTrace(System.out);
}
dbconn.commit
}
catch (SQLException ex){
ex.printStackTrace(System.out);
try{
dbconn.rollback();
}
catch (Exception rollback){
rollback.printStackTrace(System.out);
}
}
catch (Exception e){
e.printStackTrace(System.out);
try{
dbconn.rollback();
}
catch (Exception rollback){
rollback.printStackTrace(System.out);
}
}
finally
{
}
}
catch (SocketTimeoutException ex){
ex.printStackTrace();
}
catch (IOException ex){
ex.printStackTrace();
}
catch (Exception ex){
ex.printStackTrace(System.out);
}
finally{
try{
if ( dbconn != null ){
dbconn.close();
}
else{
System.out.println("dbConn is null in finally close");
}
}
catch(SQLException ex){
ex.printStackTrace();
}
try{
if ( writeBuffer != null ){
writeBuffer.close();
}
else{
System.out.println("w is null in finally close");
}
}
catch(IOException ex){
ex.printStackTrace(System.out);
}
}
}
}
终结者分析 sun.misc.Launcher $ ExtClassLoader @ 0xe003a648(50%) 大小:11.2 MB类:196对象:201.7k类加载器:7
共有91个对象实现了finalize方法。
Histogram of Objects with Finalize Method
Class Name Objects Shallow Heap
com.mysql.jdbc.JDBC4Connection
First 10 of 38 objects 38 42,560
java.net.SocksSocketImpl
First 10 of 39 objects 39 4,368
java.util.jar.JarFile
All 6 objects 6 384
java.util.zip.Inflater
All 6 objects 6 192
java.util.concurrent.ScheduledThreadPoolExecutor
All 1 objects 1 80
java.util.concurrent.ThreadPoolExecutor
All 1 objects 1 72
Total: 6 entries
91 47,656
来自
的终结者分析(46%) 大小:13.6 MB类别:578对象:304.8k类加载器:4
共有19,341个对象实现了finalize方法。
Class Name Objects Shallow Heap
java.net.SocksSocketImpl
First 10 of 18,354 objects 18,354 2,055,648
com.sun.mail.smtp.SMTPTransport
First 10 of 162 objects 162 25,920
java.io.FileOutputStream
First 10 of 742 objects 742 23,744
com.mysql.jdbc.JDBC4Connection
First 10 of 15 objects 15 16,800
java.util.jar.JarFile
First 10 of 20 objects 20 1,280
java.util.zip.Inflater
First 10 of 25 objects 25 800
java.util.concurrent.ThreadPoolExecutor
All 8 objects 8 576
sun.net.www.protocol.jar.URLJarFile
All 5 objects 5 400
java.util.concurrent.ScheduledThreadPoolExecutor
All 2 objects 2 160
java.lang.ClassLoader$NativeLibrary
All 4 objects 4 128
java.io.FileInputStream
All 3 objects 3 96
sun.jdbc.odbc.JdbcOdbcDriver
All 1 objects 1 24
Total: 12 entries
19,341 2,125,576
org.rzo.yajsw.boot.WrapperClassLoader @ 0xe02818c0(4%)的终结器分析 大小:966.3 KB类:361对象:19.9k类加载器:3
共有22个对象实现了finalize方法。
Histogram of Objects with Finalize Method
Class Name Objects Shallow Heap
java.util.jar.JarFile
First 10 of 11 objects 11 704
java.util.zip.Inflater
All 10 objects 10 320
java.util.concurrent.ThreadPoolExecutor
All 1 objects 1 72
Total: 3 entries
22 1,096
Histo Live Results。
num #instances #bytes class name
----------------------------------------------
1: 6001 18078232 [I
2: 44562 7196072 [B
3: 103183 6054240 [C
4: 31832 4786936 <constMethodKlass>
5: 31832 4340240 <methodKlass>
6: 31638 3543456 java.net.SocksSocketImpl
7: 20127 3542352 com.mysql.jdbc.JDBC4ResultSet
8: 41022 3461576 [Ljava.util.HashMap$Entry;
9: 104185 3333920 java.lang.String
10: 20198 3070096 com.mysql.jdbc.StatementImpl
11: 20323 2926512 com.mysql.jdbc.Field
12: 60329 2895792 java.util.TreeMap
13: 2343 2800032 <constantPoolKlass>
14: 61239 2449560 java.util.TreeMap$Entry
15: 149690 2395040 java.lang.Object
16: 41000 1968000 java.util.HashMap
17: 2343 1895080 <instanceKlassKlass>
18: 1954 1569536 <constantPoolCacheKlass>
19: 31623 1517904 java.net.SocketInputStream
套接字的初始开始
71: 2 224 java.net.SocksSocketImpl
176: 1 32 java.net.Socket
202: 1 24 java.net.InetSocketAddress
206: 1 24 java.net.ServerSocket
运行50个套接字后。
19: 52 5824 java.net.SocksSocketImpl
37: 50 2400 java.net.SocketInputStream
48: 51 1632 java.net.Socket
88: 8 384 java.net.SocketOutputStream
95: 8 320 java.net.SocketTimeoutException
135: 7 112 java.net.Socket$3
136: 7 112 java.net.Socket$2
229: 1 24 java.net.ServerSocket
答案 0 :(得分:1)
512 MB听起来不那么多,可能不值得您花时间尝试进一步优化它。 BTW 512 Mb是512兆位。
中期和长期生活的物体最终都会老一代。
您可以使用内存分析器优化代码以减少字符串的使用。您可以使用StringBuilder来回收对象并降低GC压力,这是导致对象在终身空间中错误结束的常见原因。
采取它的极端,你可能会发现你可以消除所有字符串生成,但我怀疑它是值得的,增加1 GB的内存可能更简单/更便宜。