一、Java的内存模型
Java的内存模型包括:
1.程序计数器:负责管理指令的执行顺序,并且因为虚拟机的多线程是来回切换的。当切换回来时需要记录下上个线程的执行状态。所以每个线程都有一个程序计数器
2. 虚拟机栈区:负责虚拟机方法模型的管理,每一个方法在里面都会形成一个栈帧,每个栈帧管理方法的内存模型。会抛出OOP或者StackoverFlow错误
3. native方法区:负责管理c++的方法
4.Java堆区:负责存放对象的实例,并且被线程所共享,虚拟机GC时处理的就是这个内存块。通过-Xms来控制
5.方法区:用于加载已经被系统处理的类信息,静态信息,常量等信息。它包含一个运行时常量池存储类的信息
6.直接内存:在Java1.4以后加入NIO,其中它的DirectBuffer可以直接在物理内存中分配空间,并且在Jvm内存中申请一块内存维护指向物理内存的引用。通过操作这个引用来减少native和堆内存间相互复制值产生的消耗
二、new对象的过程
在new一个对象时
1.在运行时常量池检查是否加载,解析,初始化过
2.分配一块空间给这个对象,如果堆的内存规整使用指针碰撞,如果不规整采用引用列表
3.初始化归零对象的值
4.调用init方法完成初始化
三、虚拟参数设置
将堆的最大最小参数设置一样,可以避免堆自动扩展
-Xms:堆的最小参数
-Xmx:堆的最大参数
-Xss: 栈内存容量设置
-XX:MaxPermSize:方法区最大容量
-XX:MaxDirectMemorySize:本机直接内存
-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails
XX:SurvivorRatio=8
四、线程能获得的容量
一个方法能瓜分的内存是:
操作系统分配的内存 - Xmx - 方法区内存 - 虚拟机进程内存 - 本地方法区
如果在方法中创建线程,那么上面的内存由线程和栈瓜分,栈分配的越多,线程能创建的数量越小