本文参考文章
https://blog.csdn.net/ctwy291314/article/details/84872271
https://blog.csdn.net/qq_18344939/article/details/52224185
JVM管理的内存可以总体划分为两部分:Heap Memory和Native Memory。Heap Memory及其内部各组成的大小可以通过JVM的一系列命令行参数来控制;Native Memory没有相应的参数来控制大小,其大小依赖于操作系统进程的最大值(对于32位系统就是3~4G,各种系统的实现并不一样),以及生成的Java字节码大小、创建的线程数量、维持java对象的状态信息大小(用于GC)以及一些第三方的包,比如JDBC驱动使用的native内存。
如下图所示:
java垃圾回收将堆分成了3个区域
年轻代,老年代和永久代
这样划分的目的是为了优化GC的性能
不同代采用不同的算法进行垃圾回收
1.年轻代
HotSpot JVM把年轻代分为了三部分:1个Eden区和2个Survivor区(分别叫from和to)。
每次GC时年轻代中的对象很多都会死亡,只有少量存活对象,所以采用复制算法,代价比较低,且复制算法不会产生内部碎片。
2.老年代
老年代对象的存活率高,适合采用标记算法
3.永久代
用于存放静态文件,如今Java类、方法等。持久代对垃圾回收没有显著影响,但是有些应 用可能动态生成或者调用一些class,例如Hibernate 等,在这种时候需要设置一个比较大的持 久代空间来存放这些运行过程中新增的类。持久代大小通过-XX:MaxPermSize=进行设置。
持久带补充:持久带也称为方法区
方法区:方法区存储每一个java类的结构信息:比如运行时常量池,字段和方法数据,构造函数和普通方法的字节码内容以及类、实例、接口初始化时需要使用到的特殊方法等数据。
方法区也被称为永久代,如果不显示指定的话,GC回收的目标仅针对方法区的常量池和类型卸载
4.native memory的作用:
1.管理java heap的状态数据(用于GC);
2.JNI调用,也就是Native Stack;
3.JIT(即使编译器)编译时使用Native Memory,并且JIT的输入(Java字节码)和输出(可执行代码)也都是保存在Native Memory;
4.NIO direct buffer。对于IBM JVM和Hotspot,都可以通过-XX:MaxDirectMemorySize来设置nio直接缓冲区的最大值。默认是64M。超过这个时,会按照32M自动增大。
5.对于IBM的JVM某些版本实现,类加载器和类信息都是保存在Native Memory中的