关于JVM一些知识的粗浅认识

1. Java是如何跨平台的

Java将源代码编译成Class文件,是基于字节码的,字节码是以byte为单位存储的文件,和跨平台结合起来,它就是描述程序要运行的虚指令的集合,而这个虚指令与任何平台无关,Java虚拟机认识它,Java虚拟机将它翻译为对应的OS指令。Java虚拟机会为每个OS平台编写对应的JRE运行时环境,与OS动态链接,将这些虚指令编码翻译为对应操作系统的汇编指令信息,即可在对应的OS上调用执行了。


2. Java中“对象存放位置”小结


a. 当实例化一个对象时,如果对象不是特别大或没有达到参数限制,那么都会在Eden区分配空间来存放这个对象。

b. 在不断创建对象的过程中,Eden区域会满,满的时候就会开始做Young GC(也称为Minor GC),当第一次发生Minor GC时,会在S0或S1中选择一个区域将Eden区域中活着的对象写进去(这里假设第一次使用的是S0),如果S0区域放不下,则会放入Old区域,然后清空Eden区域。

c. 当第二次发生Minor GC时,将会将“Eden区域中活着的对象和S0区域中活着的对象”拷贝到S1空间中,如果S1区域存放不下,则会进入Old区域,最后将Eden和S0两个区域清空。

d. 第3次就将Eden+S1区域中活着的对象拷贝到S0,将Eden和S1区域清空,以此类推,如此S0和S1区域始终有一个是空的。

e. 如果代码没有问题,90%以上的对象在创建后都会被马上注销掉,即使Young空间很大,但是活下来的对象是少数的,那么寻找活着的对象就会很快,即Minor GC很快。由于活下来的对象不多,所以存放活下来的对象的空间并不需要太大,因此就产生了Survivor区域,也正因为如此,S区域不会太大。

f. 每次拷贝时,如果S0或S1区域放不下,就会进入Old区域,Old区域满时就会开始做Full GC,在Minor GC时,Survivor区域存放不下,对象进入Old区域的过程通常叫做“晋升”,在“晋升”时,JVM会检测到Old区域是否有足够空间来存放这个对象,如果不足,就会先做一次Full GC在做晋升。

g. 当Perm区域满的时候,也会导致Full GC。

h. Class被加载,其实是被加载到永久代(PermGen),Class也占用空间,,而且并不小,Class本身算是永久代的最大用户,但永久代还存储着其他内容。当我们调用String对象的intern()方式时,它会在永久代中一块所谓的“常量池区域”中查找是否有相同值的常量(使用equals()方法进行匹配),如果没有找到,就在永久代中生成一个具有相同值的String对象并返回这个String对象的引用;如果找到则直接返回所找到的String对象的引用地址。

i. 静态(static)数据也是存放在永久代中,如果是静态引用,它的生命周期将是从所在类加载到所在类卸载,换句话说,一旦静态引用来引用对象,通常对象是长命的。

j. java.lang.OutOfMemoryError: Java heap space  这就是Java堆空间的溢出,也就是说,Old区域剩余的内存,已经无法满足将要晋升到Old区域的对象大小。


你可能感兴趣的:(jvm)