1、Java对象的内存结构
1)32位系统下存储对象头所需空间 16字节:Class指针4字节 + Mark Word空间4字节 若是数组再 + 4字节表示数组的长度
2)64位系统及64位JVM:开启指针压缩,Class指针4字节 + Mark Word空间8字节
3)32位系统,使用new Object(),JVM分配8个字节的空间
4)32位系统,使用new Integet(),对象里包含一个int 值,占4个字节,总共加起来4+8 = 12字节,按照对象8字节对齐说法,将需要16个字节
5)静态属性所占用的空间通常不计算到对象本僧的空间上,因为他的引用在方法区
6)无继承关系的对象默认排布:long/double -> int/float -> short/char -> byte/boolean -> Reference
7)一个对象在HashMap切套层次:HashMap对象 -> Entry数组 -> Entry列表 ->Entry对象 ->找到value引用以及对应的对象值
2、常见的OOM现象
1)HeapSize 的 OutOfMemoryError:堆溢出,解决方案:
public class HeapOOM{
public static void main(String[]args){
List<String> list = new ArrayList();
while(true){
list.add(“内存溢出啦”)
}
}
}
a)提升代码运行速度,代码速度起来,相同对象生存时间或许会更短了,会更快的被当作垃圾
b)object =null 可以辅助gc
c)修改参数配置,设置堆的大小
2)永久带的 PermGen OOM 的OutOfMemoryError:永久带中放着class和一些常量
jdk1.7以后String 常量不再存储在PermGen中3)直接内存DirectBuffer OOM:是C Heap的一部分
public class StringInternPernGenOOM{
public static void main(String[]args){
int i = 0;
List<String> list = new ArrayList();
while(true){
list.add((“快点死掉吧”+ i++).intern() )
}
}
}
4)-XX:MaxDirectMemorySize:设置直接内存的大小,当申请的直接内存只要大于该内存就会包内存溢出
5)-XX:PrintGCDetails:查看GC过程
6)程序调用System.gc():JVM不一定立刻去做,也不一定会去做GC
7)-XX:+DisableExplicitGC:系统不会在System.gc()动作发生时去做FULL GC 动作,及时是空间不足,也不会去做
8)自己释放直接内存:
ByteBuffer byteBUffer = ByteBuffer.allocateDirect(256*1024*1024);
//直接释放掉内存,无需等系统执行垃圾回收
(DirectBuffer)byteBuffer.cleaner().clean();