jvm的内存模型,和gc理解

1,在jvm内存模型中,分为堆区和栈区和方法区,堆区存储的是所有的java对象,包括对象的类对象,堆区只有一个,被所有线程共享,但是不存储基本数据类型和对象引用

2,每一个线程包含一个栈区,栈中存储的是基本数据类型和对象引用,每一个栈中的数据都是私有的其他线程栈不可见,根据不同的jvm启动参数闲置每一个线程栈的内存大小也是由限度的,如果在一个线程中创建过多的基本数据类型或者设置不当导致栈内存很小是可能导致内存溢出的,而在线程执行中调用的每一个方法就都是栈中的一帧,所以在一个线程中调用过多的方法(一般是递归导致)也会出现异常,超出栈的最大深度

3,jvm启动,将类加载进vm存储的位置就是在方法区,包括类的静态属性(同时会在堆中生成一个该类的类对象Class),此方法区也是被所有的线程栈共享的

4,jvm中的对象分代,分为新生代,老年代和永久代,执行分代回收gc策略

4.1,永久代中存放的都是类信息和常量信息等,永久代会发生gc回收那些无用的类和常量,当类的对象都被回收,类的加载器也被回收,类的类对象也不在持有引用时即可被回收,永久代的gc不一定需要执行,可以通过jvm启动参数进行控制-Xnoclassgc

4.2,新生代,关于新生代,还分为3个区域:Eden区和Survivor0和Survivor1,这些区的空间大小一般比较小,对象的创建一般都是发生在Eden区,当该区域无法再进行新对象创建时就会触发Minor GC,清除没有持有引入的对象,然后将剩余的对象移入Survivor0,清空Eden区,然后再次发生Minor GC对Eden区进行清理时同时清理Survivor0,清除没有引用的对象同时将剩余对象转入Survivor1,在每次Minor GC的时候将Eden的存活对象移入Survivor区同时将两Survivor区中的一个进行清理和导入,当一个对象在Survivor中经历多次清理都依然存活即可被转入老年代,这个次数可以在jvm启动时自定义

4.3,老年代,当对象转入老年代,一般就不会在发生gc,当老年代的内存不足时才会触发老年代区的gc,此时的gc就是:Full GC,这个gc执行的过程会很慢。Full GC与YoungGC是无法完全区分开来的,很多情况下,Full GC是由Minor GC导致的

查询整理:触发FullGC的时机:

a,老年代内存分配已满;b,非堆区(栈)内存分配已满;c,调用System.gc()

严重声明,除非特殊情况,在程序中不要进行主动gc的调用,System.gc(),因为会触发Full GC,这是一个全区域的垃圾回收,执行很慢,会严重影响程序性能

你可能感兴趣的:(javaweb)