java 内存管理详述

来源:互联网 发布:新加坡叫车软件 编辑:程序博客网 时间:2024/06/05 11:26
对JVM的一次系统整理.有些东西的描述并不严谨,或者在不同平台和不同版本上关同一点的内容会用很大出入。这里不再细分。只是对JVM 有清楚认识。

1 Java虚拟机的种类

1.1  Oracle Java虚拟机
原Sun Java虚拟机
原BEA JRockit
两种Java虚拟机,都运行在Windows、Linux、Solaris平台
1.2  HP Java虚拟机:
与SUN JDK基本兼容,有自己独特的启动参数
运行在HP UNIX上
1.3  IBM Java虚拟机:
与Sun JDK基本兼容
启动参数的写法风格与Sun JDK、HP JDK非常不同
主要用于WebSphere、跑在AIX上的中间件服务器
1.4  开源 Java虚拟机:
与SUN JDK兼容 

2 选择合适的Java虚拟机
2.1  选择稳定的JDK:
刚刚GA的版本不稳定,比如1.5.0_00 1.6.0_00
刚增加新特性的版本不稳定,比如1.5.0_07  1.6.0_14
安装JDK之前,先看厂商的Release Notes
2.2 根据平台和应用,选择合适厂商的JDK:
HP-UX只能选择HP JDK,AIX只能选择IBM JDK
Windows、Linux可以选择SUN JDK和JRockit
Solaris平台,最好使用SUN JDK
开源JDK,目前生产环境中用的极少

3 JVM内存在哪
3.1 JVM内存在哪
操作系统把内存分成两块。一个是KernelSpace ,另一块 UserSapce
KernelSpace指的是 操作系统保留内存,即供操作系统使用的内存。
UserSapce  指的是供OS使用之外的内存。像我们平时用的应用程序包括JVM都是跑在UserSapce。
不同操作系统下KernelSpace 和 UserSapce 大小和比例是不一样的。

3.2 内存
内存 = Java 内存 + 本地内存+ 加载的可执行文件和库 + 操作系统保留内存

3.3 java 内存
分为Java 堆内存(heap)和Permanent区(Sun/Hp JDK,只针对这个版本)
Java 堆内存(heap):
是 JVM 用于分配 Java 对象的内存,包含活动对象 和不可用对象
堆大小通常是在服务器启动时使用 java 命令中的 –Xms(最小) –Xmx(最大)标志来定义。
Permanent区:
是Sun JDK和HP JDK用来加载类(class)的专门的内存区
这个区域不归属Java 堆内存(heap)范围
如果Java应用很大,例如类(class)很多,那么建议增大这个区域的大小来满足加载这些类的内存需求
通过–XX:PermSize=***M –XX:MaxPermSize=***M调整

Java 内存 主要指的就是堆。即存放对象的堆内存。当然也包括持久区的概念,有人会叫他方法区,其实class中的声名的方法也有部分内容存放在codecache里(一块内存区域),准确来产方法区是一个实现方式,即开辟出一块内存来存放方法。但不同的JVM版本在这会有不同的实现,可能在以后升级中会去掉方法区这种实现,把方法放到堆中统一进行管理。
而我们常说的GC,其实管理的内存就是上面提到的java heap和方法区。网上有人提到方法区内是不能被GC,其实是可以的。可见Java HotSpot(TM)官方网站。

3.4 native heap
本地内存:
是 JVM 用于其内部操作的本地内存(非Java内存)
JNI 代码和第三方本地模块(例如,本地 JDBC 驱动 程序)也使用本地内存
最大本地内存大小取决于以下因素:
操作系统进程内存大小限制
已经指定用于 Java 堆的内存

这里简单介绍下JNI:
JNI是Java Native Interface的缩写,中文为JAVA本地调用。从Java1.1开始,Java Native Interface(JNI)标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是 C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。

3.5 native
Native Method就是java调用非java代码的接口。

4.内存不足时 出现一些情况
4.1 GC次数过多,导致占用时间过长
GC占用时间过长--系统明显感觉比较慢
Heap区、Perm区分配内存总量够用
通过verbose gc、jstat观察,GC占用时间超过总时间的5%甚至更高
4.2 内存不足错误
内存不足错误--明确显示出java.lang.OutOfMemoryError
没有空闲内存可供 JVM 或本地代码用于分配新对象或内存块
在 Java 堆或本地内存中都可能发生
4.3 内存泄漏错误--没有错误信息,但是内存几乎耗尽
已经分配好的内存或对象,当不再需要,没有得到释放
内存曲线是一条斜向上的曲线
对 Java 堆或本地内存都可能产生这个问题
通常最终的状态就会导致 OOM 错误


上面的红色的部分指的就是加载的可执行文件和库 + 操作系统保留内存
Java内存和其他一些应用程序所使用的内存都是蓝色部分。
Java内存又可细分为java heap,指的是堆 和持久区方法区。
native heap,用于其内部操作的本地内存(非Java内存)JNI 代码(优化代码载入)
    和第三方本地模块(例如,本地 JDBC 驱动程序)使用主要取决于JVM代码生成,
最大本地内存大小取决于以下因素:
操作系统进程内存大小限制
已经指定用于 Java 堆的内存
“加载的可执行文件和库+系统保留内存”不同操作系统和应用不一样
计算机的物理内存  = RAM + 交换空间 ,进程的虚拟内存由 OS 映射到物理内存

3.4 内存不足时,出现的一些情况:
3.4.1 Heap区、Perm区分配内存总量够用
通过verbose gc、jstat观察,GC占用时间超过总时间的5%甚至更高
3.4.2内存不足错误
java.lang.OutOfMemoryError
没有空闲内存可供 JVM 或本地代码用于分配新对象或内存块
在 Java 堆或本地内存中都可能发生
ava内存--包括heap堆内存和permanent区
本地内存--包括JVM进程内存和java使用的第三方本地代码
同样这类OOM产生的问题也是分成正常使用耗尽和无释放资源耗尽两类
无释放资源耗尽很多时候不是程序员自身的原因,可能是引用的 第三方包的缺陷,例如很多人遇到的Oracle 9 JDBC驱动在低版本中有内存泄露的问题
另一种情况就是正常消耗Native Heap Memory,对于Native Heap Memory的使用主要取决于JVM代码生成,线程创建,用于优化的临时代码和对象产生
3.4.3内存泄漏错误
已经分配好的内存或对象,当不再需要,没有得到释放
内存曲线是一条斜向上的曲线
对 Java 堆或本地内存都可能产生这个问题
通常最终的状态就会导致 OOM 错误

5 classloader
http://luyuanliang.iteye.com/admin/blogs/1077782

6 GC
1.gc对象
2.gc算法
3.gc收集器
原创粉丝点击