weblogic出现永久代内存溢出,以前处理这种情况就是加大永久代,但现在已经加到1GB还是不够,先临时加到1.5G,监控GC日志,永久代在不断的增长,说明在发送内存泄露。
java.lang.OutOfMemoryError: PermGen space
Dumping heap to java_pid92235.hprof ...
1.分析dump文件,根据定位堆内存溢出的经验,找到主要矛盾。
Java Basics --> class loader explorer 查找哪个类最多,问题来了,无法定位出来,类太多了,无法归纳。
2.有两个JVM参数,用来跟踪类加载和卸载的信息,是乎可以从这里下手,哪些没有被卸载的类找出来。
-XX:+TraceClassLoading和 -XX:+TraceClassUnloading用来打印类被加载和卸载的过程信息,如下:
[Loaded java.lang.Object from /data/jdk1.6.0_45/jre/lib/rt.jar]
[Loaded java.io.Serializable from /data/jdk1.6.0_45/jre/lib/rt.jar]
[Loaded java.lang.Comparable from /data/jdk1.6.0_45/jre/lib/rt.jar]
[Loaded java.lang.CharSequence from /data/jdk1.6.0_45/jre/lib/rt.jar]
[Loaded java.lang.String from /data/jdk1.6.0_45/jre/lib/rt.jar]
[Loaded java.lang.reflect.GenericDeclaration from /data/jdk1.6.0_45/jre/lib/rt.jar]
[Loaded java.lang.reflect.Type from /data/jdk1.6.0_45/jre/lib/rt.jar]
.....................................................................
[Unloading class com.webservice.material.wms.client.physinventory.IPhysInventoryClientService]
[Unloading class com.groupmaterial.performance.appservice.IPerformanceService]
[Unloading class com.comtop.usermanagement.usernode.UserNode]
[Unloading class com.material.inventory.issue.exception.IssueException]
[Unloading class com.material.purchase.contractmark.model.ContractPerformGradeItemVO]
[Unloading class com.ps.internal.projectinfo.appservice.ICommuniSubprojectVInternalBizService]
[Unloading class com.ps.internal.projectinfo.model.ScheduleItemTemplateDTO]
打印了大量这样的信息,需要写一个程序解析,以下是我写的程序:
--初始化数据开始
drop table load_class purge;
truncate table load_class;
create table load_class
(
nu number,
action varchar2(20),
class_name varchar2(1000),
class_file varchar2(1000)
);
--执行java代码导入之后,处理一些特殊的格式
update load_class
set action = replace(action, '[', ''),
class_file = replace(class_file, ']', ''),
class_name = replace(class_name, ']', '');
commit;
update load_class
set class_name = replace(class_name, 'file:', ''),
class_file = replace(class_file, 'file:', '');
commit;
select count(1) from load_class;
--显示加载且没有卸载的类
drop table load_class_result purge;
create table load_class_result as
with res as
(select count(*) over(partition by action,class_name order by nu asc) rn,
t.*
from load_class t)
,res1 as (select rn,class_name from res a where a.action='Loaded'
minus
select rn,class_name from res b where b.action='Unloading')
select b.* from res1 a, res b where a.rn= b.rn and a.class_name= b.class_name;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
/**
* [Loaded java.lang.ClassNotFoundException from /usr/local/jdk1.6/jre/lib/rt.jar]
* [Unloading class com.material.externalinterface.fmis.impl.FmisBizService]
*
*/
public class PermAla {
static final String driver_class = "oracle.jdbc.driver.OracleDriver";
static final String connectionURL = "jdbc:oracle:thin:@10.11.115.164:1521:orcl";
static final String userID = "test";
static final String userPassword = "test";
public static void readTxtFile(String filePath){
Connection con = null;
String s_sql = "insert into load_class values(?,?,?,?)";
PreparedStatement pstmt = null;
int i=0;
try {
Class.forName (driver_class).newInstance();
con = DriverManager.getConnection(connectionURL, userID, userPassword);
pstmt = con.prepareStatement(s_sql);
con.setAutoCommit(false);
String encoding="GBK";
File file=new File(filePath);
InputStreamReader read = new InputStreamReader(
new FileInputStream(file),encoding);//考虑到编码格式
BufferedReader bufferedReader = new BufferedReader(read);
String lineTxt = null;
String[] lineTxtArray= null;
while((lineTxt = bufferedReader.readLine()) != null){
if(lineTxt.indexOf("[Loaded")==0 ) {
lineTxtArray = lineTxt.split(" ");
pstmt.setInt(1, i);
pstmt.setString(2, lineTxtArray[0]);
pstmt.setString(3, lineTxtArray[1]);
if(lineTxtArray.length ==4) {
pstmt.setString(4, lineTxtArray[3]);
}else{
System.out.println(lineTxt);
}
pstmt.addBatch();
i++;
} else if(lineTxt.indexOf("[Unloading")==0){
lineTxtArray = lineTxt.split(" ");
pstmt.setInt(1, i);
pstmt.setString(2, lineTxtArray[0]);
pstmt.setString(3, lineTxtArray[2]);
pstmt.addBatch();
i++;
}
if(i % 10000 == 0){
pstmt.executeBatch();
con.commit();
}
}
con.commit();
read.close();
} catch (Exception e) {
System.out.println("读取文件内容出错,行数:"+i);
e.printStackTrace();
}finally{
if(pstmt != null){
try {
pstmt.close();
} catch (Exception e) {
e.printStackTrace();
}finally{
pstmt = null;
}
}
if(con != null){
try {
con.close();
} catch (Exception e) {
e.printStackTrace();
}finally{
con = null;
}
}
}
}
public static void main(String argv[]){
String filePath = "E:\\20161213\\nohup.out";
readTxtFile(filePath);
}
}
..............................................................
以下是我负责的应用类的加载情况,我粗略的估计一下,1万个类100M。
__JVM_DefineClass__(反射产生的类) | 21865 |
EAR/APP-INF/lib | 25326 |
EAR/APP-INF/classes | 21275 |
wls1035 | 19007 |
Server1/cache/EJBCompilerCache | 5996 |
/data/jdk1.6.0_45/jre | 3485 |
weblogic.utils.classloaders.GenericClassLoader sun.misc.Launcher$AppClassLoader weblogic.utils.classloaders.ChangeAwareClassLoader |
2511 |
jsp_temp | 527 |
http://stackoverflow.com/questions/16130292/java-lang-outofmemoryerror-permgen-space-java-reflection