虚拟机内存管理

虚拟机进行new对象指令时是先分辨是否能引用,然后判断是否加载(类加载),接着就是分配内存,如果gc带有压缩整理功能,则分配方式为空闲列表(CMS基于Mark-Sweep算法收集器),如果不带,就是用指针碰撞的方式分配,Serial,ParNew带Compact的收集器这类的

对象的创建在虚拟机中是如何保证安全的

1:同步(类似于加锁)2:分配不同的创建区域(把两者想分配在不同区域,自然就不会有冲突的情况)



如何使用对象

1:句柄访问,在栈中有一个reference,存的是句柄池句柄的地址,句柄则包含了所有对象的数据类型和类型数据各自的地址,好处:在复制清除中,只需要修改reference的值,就可以,不需要移动太多的数据

2:直接指针访问:reference存的是对象的地址,好处:速度快,减少开销



各个位置内存溢出的原因

堆溢出:不断创建新对象,并保证gc到达对象之间有可达路径避免被清除.对象数量大于最大容量就会oom

解决办法:确认内存中的对象是否必须存在:

虚拟机栈溢出和本地方法栈溢出

1:线程请求的栈深度大于虚拟机所允许的最大深度,抛出StackOverFlowError

2:虚拟机在扩展栈时,没有足够的内存空间,抛出OutOfMemoryError

解决办法:减少单个线程的内存,减少最大堆和最小的栈容量来换取更多的线程(单个线程的内存越大,越有可能出现内存溢出的情况,在多线程的情况下,减少单个线程的内存大小,可以尽量避免出现栈溢出的错误)


方法区和运行时常量池溢出:

原因:运行时产生大量的类填满方法区,

常见的:大量jsp或产生jsp文件的应用,jsp第一次运行会编译成java类,同个类被不同加载器加载,会被视为不同的类CGlib动态生成的class


本机直接内存溢出

没有申请分配内存,却通过其他方式来获取实例进行内存分配(想要内存,却没申请)

你可能感兴趣的:(虚拟机内存管理)