https://www.jianshu.com/p/424a920771a3
写的很赞。
注意:OOP-Klass是hotspot的JVM实现原理,其他JVM的实现可能不一样。、
OOP表示java实例,Klass表示class。
Klass: 包含元数据和方法信息,用来描述Java类
OOP: Ordinary Object Pointer (普通对象指针),它用来表示对象的实例信息,看起来像个指针实际上是藏在指针里的对象
https://www.jianshu.com/p/59f98076b382
一般认为java实例的创建,都会在堆上开辟内存创建实例。但是在堆上的哪个区,却是不一定的。比如:最常见是在Eden区分配,如果是Eden区不够(不够会触发一次Monitor GC 还不够)或者大对象(超过JVM配置),会在Old区分配。反正不够怎样,大概率情况会在堆上分配。但是有了JIT技术,一切都不一样啦。
这篇文章分析的很详细:参考文章:求你了,别再说Java对象都是在堆内存上分配空间的了!
首先需要明确,OOM是JVM的行为。只有JVM内存不足,才会报OOM。
我们先思考下IO流占用了哪些资源?如下代码:
private static void readNoClose(int num, String fileName){
try{
InputStream in = new FileInputStream(fileName);
byte[] tempbytes = new byte[1024];
int byteread = in.read(tempbytes);
System.out.println("num=" + num + ",size=" + byteread);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
下面的代码,我们申请1M空间接收文件内容。但是我们把流in仅仅放在方法类。循环调用readNoClose方法。
上面这段代码,在方法执行期间,占用的资源有:
有人可能会问,不关闭会造成内存泄漏,内存泄漏会造成OOM。谁跟你说泄漏就会造成OOM?这里的泄漏,准确来说不是JVM内存泄漏,而是操作系统所在的内存泄漏。要泄漏也是非JVM管理的内存。JVM压根管不到,何来OOM。
上面代码泄漏的仅仅是FD,而FD占用内存很小。在还没来得及把内存泄漏满,操作系统就会报文件描述符太多,无法再创建。因为同一个文件上,所能打开的FD数量是有限的。
所以上面代码本地运行就会报如下错误。
java.io.FileNotFoundException: /Users/xxx (Too many open files)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at java.io.FileInputStream.<init>(FileInputStream.java:93)