岁月如哥
人生非梦
posts - 50,comments - 144,trackbacks - 0
首先引用jdk1.5api的doc:
内存 
Java 虚拟机的内存系统管理以下类型的内存:
1. 堆 
Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在 Java 虚拟机启动时创建的。对象的堆内存由称为垃圾回收器 的自动内存管理系统回收。
堆的大小可以固定,也可以扩大和缩小。堆的内存不需要是连续空间。

2. 非堆内存
Java 虚拟机管理堆之外的内存(称为非堆内存)。 
Java 虚拟机具有一个由所有线程共享的方法区。方法区属于非堆内存。它存储每个类结构,如运行时常数池、字段和方法数据,以及方法和构造方法的代码。它是在 Java 虚拟机启动时创建的。 

方法区在逻辑上属于堆,但 Java 虚拟机实现可以选择不对其进行回收或压缩。与堆类似,方法区的大小可以固定,也可以扩大和缩小。方法区的内存不需要是连续空间。

除了方法区外,Java 虚拟机实现可能需要用于内部处理或优化的内存,这种内存也是非堆内存。例如,JIT 编译器需要内存来存储从 Java 虚拟机代码转换而来的本机代码,从而获得高性能。

  在网上找到如下的jsp来监视内存使用情况:
 
<%@ page import="java.lang.management.*" %>
<%@ page import="java.util.*" %>
<html>
<head>
  
<title>JVM Memory Monitor</title>
</head>

<body>
<table border="0" width="100%">
<tr><td colspan="2" align="center"><h3>Memory MXBean</h3></td></tr>
<tr><td
width="200">Heap Memory Usage</td><td><%=
ManagementFactory.getMemoryMXBean().getHeapMemoryUsage()
%></td></tr>
<tr><td>Non-Heap Memory
Usage
</td><td><%=
ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage()
%></td></tr>
<tr><td colspan="2">&nbsp;</td></tr>
<tr><td colspan="2" align="center"><h3>Memory Pool MXBeans</h3></td></tr>
<%
        Iterator iter 
= ManagementFactory.getMemoryPoolMXBeans().iterator();
        
while (iter.hasNext()) {
            MemoryPoolMXBean item 
= (MemoryPoolMXBean) iter.next();
%>
<tr><td colspan="2">
<table border="0" width="100%" style="border: 1px #98AAB1 solid;">
<tr><td colspan="2" align="center"><b><%= item.getName() %></b></td></tr>
<tr><td width="200">Type</td><td><%= item.getType() %></td></tr>
<tr><td>Usage</td><td><%= item.getUsage() %></td></tr>
<tr><td>Peak Usage</td><td><%= item.getPeakUsage() %></td></tr>
<tr><td>Collection Usage</td><td><%= item.getCollectionUsage() %></td></tr>
</table>
</td></tr>
<tr><td colspan="2">&nbsp;</td></tr>
<%%>
</table>
</body>
</html>

使用的结果(JDK1.5)正如doc描述:
  
从检测的结果来看,non-heap memory中,包含了perm gen和一部分jvm自用的内存
其中heap memory的最大值即我们指定的启动参数 -Xmx1024m所指定的1024m
而Perm Gen的最大值即为我们指定的启动参数 -XX:MaxPermSize=128m 所指定的128m(不指定默认为64m)
一般的OutOfMemory大部分是因为上面两个配置参数不够引起的。
当然native heap 也可以产生OutOfMemory,如果os的java可用内存全部分给heap了。

如果发生oom,个人觉得首先是调整参数,比如:-server -Xms1024m -Xmx1024m -XX:PermSize=128m -XX:MaxPermSize=128m
如果参数调整之后还是oom,则需要考虑优化程序了(当然首先要把死递归,死循环排除),最好是用工具监测一下。

附我们tomcat配置参数修改方案:
 

²     Tomcat配置的修改(%tomcat%表示tomcat实际安装目录)

如果tomcat安装在Solaris环境下,打开 %tomcat%\bin\catalina.sh 文件,在文件的前面加下面红色字体的内容(注意有双引号):

    LANG=zh_CN.GB18030
             
export LANG
              
JAVA_OPTS="-server -Xms1024m -Xmx1024m -XX:PermSize=128m -XX:MaxPermSize=128m"
              
export JAVA_OPTS
              
JAVA_OPTS="$JAVA_OPTS   -Djava.awt.headless=true"
               
echo $JAVA_OPTS   

如果tomcat安装在Windows环境下,打开 %tomcat%\bin\catalina.bat 文件,在文件的前面加下面红色字体的内容(注意没有双引号):

set JAVA_OPTS=-server -Xms1024m -Xmx1024m -XX:PermSize=128m -XX:MaxPermSize=128m

打开 %tomcat%\conf\server.xml 文件,下面这行:

      maxThreads="150" minSpareThreads="25" maxSpareThreads="75"

改成:

      maxThreads="250" minSpareThreads="25" maxSpareThreads="100"


posted on 2008-09-21 20:13 岁月如歌 阅读(5254) 评论(4)  编辑  收藏 所属分类: java

FeedBack:
# re: 对jvm内存的一些理解
2008-09-21 21:52 | YYX
还有stack呢,用-Xss可以调整大小  回复  更多评论
  
# re: 对jvm内存的一些理解
2008-09-22 09:20 | #
对的,还有stack,每个线程都有一个stack,好像是在《java虚拟机规范》第二版的第三章中对jvm内存有比较详细的解释说明  回复  更多评论
  
# re: 对jvm内存的一些理解
2008-09-22 09:23 | 小赵
Code Cache是Non-heap memory  回复  更多评论
  
# re: 对jvm内存的一些理解
2008-09-22 12:19 | 向左走向右走
@小赵

谢谢提醒哈,等有时间了会重新更新一下这个图片的,会有更详细的说明
  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: