JVM内存——类加载——GC回收

https://www.cnblogs.com/fefjay/p/6305499.html
https://www.cnblogs.com/protected/p/6419217.html
https://blog.csdn.net/super_YC/article/details/71439786
https://www.cnblogs.com/fanjie/p/6916784.html
http://www.importnew.com/25295.html

JVM内存区域

用自己的简单的语言来总结下JVM的内存区域
总的来说分为线程共享区和线程私有区

线程共享区有两个部分

1.堆:主要用来存放对象实例,也是GC管理的主要区域
2.方法区:已加载类的信息,常量,静态量都存在这

线程私有区

1.虚拟机方法栈:生命周期与线程相同,里面由方法对应的栈桢构成,栈桢里面有局部变量、常量池引用,操作数栈等。
和对象引用
2.本地方法栈:服务于Native方法,提供本地方法接口
3.程序计数器:用来存放线程的下一个字节码指令,线程的恢复,跳转等也依赖于他

类的编译、加载、执行过程

其中加载又分为 类的加载、连接和初始化,连接分为验证、准备、解析。

javac main.java

类的编译主要将java文件编译为.class文件,主要生成常量池和方法字节码,常量池里面是一些常量,符号引用等。

然后

java main

此时才启动jvm进程,jvm从classpath路径下面找到main.class利用bootstrap classloader类加载器,将main.class加载到方法区去中,

然后进行验证,主要是验证.class文件的格式是否符合java和jvm的规范要求,

然后是准备阶段,为静态变量分配内存(对于静态变量的位置:java只有静态成员变量,没有static int,所以它是属于类的成员,所以位于方法区),初始化为系统默认值(此时不加载静态代码块)

解析阶段:将符号引用转化为直接引用,直接引用即指向方法的地址。

最后初始化:首先初始化类的静态变量和静态代码块。而实例类,只有在java对类的主动使用的时候才会初始化。

主动使用:

1 创建类的实例
2 访问某个类或接口的静态变量,或者对该静态变量赋值
3 调用类的静态方法
4 反射(如Class.forName(“com.shengsiyuan.Test”))
5 初始化一个类的子类(先初始化所有的父类,最后初始化本身,接口
除外,类初始化的时候,它所实现的接口不会初始化,就算字接口初始化,
父接口也不会初始化,只有当程序调用接口的静态变量的时候才会导致
接口的初始化)
6 Java虚拟机启动时被标明为启动类的类(即拥有main方法类,对应文
件名的类)

类的加载的最终产品是位于堆区中的Class 对象(即不包括触发类的主动使用)
Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口

最后类执行,由字节码转为机器码,在操作系统上面调用

gc回收

https://blog.csdn.net/xushuzhan/article/details/78522242
这篇讲的比较简单清晰

1 哪些对象可以被回收

1.1 引用计数法:引用一次+1,失效一次-1,直至为0
1.2 根搜索算法:如果一个对象和根对象之间没有引用关系,那么就可以回收

2.gc算法
均是基于根搜索的思想而实现

2.1 标记清除:遍历所有对象进行标记,清除未被标记的;内存利用率高,但是要遍历所有对象,耗费资源
这里写图片描述

2.2 复制算法:把内存分为活动和空闲区域,将活动区域标记的对象复制到空闲区域,按照内存排放对象。内存整齐,但需要2倍内存
这里写图片描述

2.3 标记整理:以上两种算法的结合,标记后,复制到gc空间
这里写图片描述

2.4 分代回收:即现在jvm使用的算法
这里写图片描述

新生代区域当GC来的时候,遵循的机制是:
1.当eden区触发GC,会将内容复制到s0,并清除eden区的内容
2.当s0区域中触发GC,会将内容复制到s1区域,并清除s1的内容
3.当s1区域触发GC,会将从s0复制过来且GC后还存活的复制到老年代中,并清空s1

GC发生的时间:这里是根据内存剩余和算法来决定什么时候触发GC,不一定要内存全满才触发,且这里说的是Minor GC,也就是用的快速回收算法实现的高效率GC,这种方法只对新生代回收。

老年代:老年代里面存放的都是从新生代复制过来的,且经过了多次GC后依旧存活的对象,如果老年代满了,则会触发FULL GC,清除新生代、老年代和永久代的内容,但是效率低。

永久带:里面存放的静态变量和静态方法。这里一般不GC,但一旦满了,也会FULL GC。

回收类型
部分回收和full gc

可以通过对老年代等内存的分配来进行内存调优,使得回收次数减少,优化资源。

3.内存分配

1.对象优先在eden区域分配:如果没有空间,则触发一次Minor Gc
2.大对象直接放入老年代:大对象指的是数组、很长的字符串等,为了
避免开销过大,直接放入老年代
3.长期存活的对象将会放入老年代: 每当对象熬过一次GC,那么它的age+1,
系统默认当这个数大于15的时候(可修改),它会进入老年代
4.动态对象年龄判断:如果在Survivor区域,当其中年龄相同的所有对象的数量
大小大于该区域中的一半的时候,年龄大于或等于该年龄的对象将会直接进入老年代。

。。。。未完。。。

猜你喜欢

转载自blog.csdn.net/weixin_38719347/article/details/82695726