1.jvm内存结构
堆:存储对象,有老年代和新生代之分。线程共享,垃圾回收器主要针对的对象,这部分的回收效率影响了vm的整体性能。
栈:每个线程独有的,主要维护栈帧,每个方法执行时,都会创建一个栈帧,来存储局部变量,出入口信息等信息,程序执行完成后会销毁栈帧。
方法区:线程共享的,存放常量,静态变量,静态代码块等
本地方法栈:每个线程独有的,用于vm的native方法,这部分有vm自动化管理。
程序计数器:存储当前的字节码文件的行指示器。
GC:垃圾回收器。
2.堆中的内存分布
新生代:Eden:该区域是最主要的刚创建的对象的内存分配区域,绝大多数对象都会被创建到这里(除了部分大对象通过内存担保机制创建到Old区域,默认大对象都是能够存活较长时间的),该区域的对象大部分都是短时间都会死亡的,故垃圾回收器针对该部分主要采用标记整理算法了回收该区域。
Surviver: Surviver:该区域也是属于新生代的区域,该区域是将在Eden中未被清理的对象存放到该区域中,该区域分为两块区域,采用的是复制算法,每次只使用一块,Eden与Surviver区域的比例是8:1,是根据大量的业务运行总结出来的规律。
老年代:
Old:该区域是属于老年代,一般能够在Surviver中没有被清除出去的对象才会进入到这块区域,该区域主要是采用标记清除算法。
总结:java堆的垃圾回收是垃圾回收器最主要的光顾对象,整体采用分代收集的策略,对不同区域结合其特点采用不同的垃圾收集算法。我们在编程中也应该关注这一块区域,尽量不适用大对象,尽可能的创建局部对象,使用过后确定废弃不用的对象及时断开引用,尽量避免使用循环的对象引用(可达性分析也是比较消耗资源的)等等。
————————————————
版权声明:本文为优快云博主「qq_34457118」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/qq_34457118/article/details/81712293
3.类加载器
类加载过程:
1.将类的.class文件读入到jvm中。
2.校验和解析
3.初始化
jvm预定义有三种类加载器:
1.根类加载器:bootstrap class loader 。加载java的核心类,C++代码实现,加载的是java的核心类库,就是java_home指定的核心jar包路径
2.扩展类加载器:Extensions class loader:负责加载jre的扩展目录,ext目录下的jar包
3.应用类加载器:加载class_path包下的类,程序可以通过ClassLoader的静态方法getSystemClassLoader来获取系统类的加载器。
4.类加载机制
1.全盘负责:所谓全盘负责,就是当一个类加载器负责加载某个Class时,该Class所依赖和引用其他Class也将由该类加载器负责载入,除非显示使用另外一个类加载器来载入。
2.双亲委派:所谓的双亲委派,则是先让父类加载器试图加载该Class,只有在父类加载器无法加载该类时才尝试从自己的类路径中加载该类。通俗的讲,就是某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父加载器,依次递归,如果父加载器可以完成类加载任务,就成功返回;只有父加载器无法完成此加载任务时,才自己去加载。
3.缓存机制:缓存机制将会保证所有加载过的Class都会被缓存,当程序中需要使用某个Class时,类加载器先从缓存区中搜寻该Class,只有当缓存区中不存在该Class对象时,系统才会读取该类对应的二进制数据,并将其转换成Class对象,存入缓冲区中。这就是为很么修改了Class后,必须重新启动JVM,程序所做的修改才会生效的原因。陕A3D7Z9
着重学习双亲委派机制

工作原理:如果一个类加载器收到了类加载请求,他并不会自己先去加载,而是将请求委托给父类的加载器去执行,如果加载器还存在其他父类加载器,进一步委托,一直到最上上面。如果父类能完成加载任务,直接返回,不然子类就会尝试自己加载。
优势:双亲委派模式好处就是java类随着它的类加载器一起具备了一种带有优先级别的层次关系,这种关系可以避免类的重复加载。可以防止Api库被随意篡改。
838

被折叠的 条评论
为什么被折叠?



