前言

java的内存分配和垃圾回收往往是影响系统性能和并发能力的主要因素,虚拟机提供许多的参数就是为了根据不同环境和请教下进行调优,没有最好的调优也没有固定的调优。需要我们深入的去了解jvm的各个垃圾回收机制和内存分配等知识。在java运行内存区域里面,java虚拟机栈、程序计数器、本地方法栈这3个伴随着线程生或者灭,是具备确定性的,所以我们主要研究java堆上面的这块内存怎么分配和回收。

判断对象存活的方法

  • 1 引用计数法:这个经典的对象存活判定算法的思路主要是给一个对象添加一个引用计数器,每当有一个引用该计数器就+1,而当一个引用失效时该计数器就-1,最后在任何时刻一旦该对象的引用计数器为0的时候该对象就不能使用。但是java里面并非采用该算法,因为该算法无法解决对象之间的相互引用的问题,也就无法导致相互引用的对象无法被GC。
  • 2 可达性分析法:商业语言例如java、c#都是采用一个“GC roots”的对象来判定该对象在一系列的引用链中不可达时,就判定该对象是不可用的,这些对象就被认为需要回收。(但是一个对象的真正销毁需要经历两次标记过程)如下图示意;

** java中有4种可以作为GC Roots的对象

  • 虚拟机栈中引用的对象
  • 方法区类静态属性引用的对象
  • 方法区常量引用的对象
  • 本地方法栈中JNI引用的对象

java的引用分类

  • 1 强引用 类似 Object o = new Object();这类引用在代码广泛存在的, GC是不会回收的
  • 2 软引用 存在一些有用但非必须的对象,在系统发生内存溢出异常强,这些对象列入第二次回收的范围
  • 2 弱引用 非必需对象且只能生存到下次GC发生之前
  • 3 虚引用 又称虚灵引用和幻影引用,一个对象设置成了虚引用的唯一目的就是当该对象被GC时收到一个系统通知

回收方法区

根据jvm虚拟机而言,其实一次GC能将堆中70~95%空间回收。但是方法区的废弃常量和无用的类都需要被回收。
无用的类,满足下面3个条件:

  • 1 该类的实例已经被回收,java堆不存在任何该类的实例
  • 2 加载该类的classloader已经被回收
  • 3 该类对于的java.lang.Class对象没有被引用,也就是无法用反射访问该类的方法。

** 垃圾收集算法

  • 1 标记-清除:首先标记出需要清除的对象,标记后统一回收。存在了效率问题 和内存空间碎片化的问题!
  • 2 复制算法:为了解决效率问题,复制算法将内存划分多块,一块满了之后复制到一块空的上面,然后回收完满的那块。在商业虚拟机里面,堆内存的新生代被分为了 一个Eden和2块Survivor区域,HotSpot默认Eden:survivor=8:1也就是说新生代的90%内存是可用内存,回收时将Eden和survivor复制到另一块survivor区域,然后再清理,如果超过了10%的话就需依赖其他内存区域如老年代。
  • 3 标记-整理算法:加入复制算法里面有一种极端情况如对象存活率很高的情况下,复制操作算法很低,就特定设计出将标记清除算法后,先将存活对象向另一端移动,然后清掉边界外的内存,这就是标记-整理算法避免了高对象存活率复制的低效率。
  • 4 分代收集算法:商业虚拟机垃圾收集采用分代收集算法,其实就是分为老年代采用标记-清理或者标记-整理,而新生代只有少量对象就采用复制算法。

** 垃圾收集器

Java Web 深入分析(12) JVM(2) 垃圾收集与内存分配的更多相关文章

  1. 深入理解JVM(5)——垃圾收集和内存分配策略

    1.垃圾收集对象 垃圾收集主要是针对堆和方法区进行. 程序计数器.虚拟机栈和本地方法栈这三个区域属于线程私有的,只存在于线程的生命周期内,线程结束之后也会消失,因此不需要对这三个区域进行垃圾回收. 哪 ...

  2. 了解JVM运行时的内存分配

    了解JVM运行时的内存分配 前言 上文中,在介绍运行时数据区域中的 JAVA 堆时,提到了 JVM 中的堆,一般分为三大部分:新生代.老年代.永久代,本文将进一步了解运行时的内存分配情况. 正文 1. ...

  3. C++ primer plus读书笔记——第12章 类和动态内存分配

    第12章 类和动态内存分配 1. 静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域运算符来指出静态成员所属的类.但如果静态成员是整形或枚举型const,则可以在类声明中初始化 ...

  4. Java Web 深入分析(6) Tomcat

    tomcat是什么:汤姆猫?Javaweb服务器? Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache ...

  5. Java Web 深入分析(5) Java ClassLoader 工作机制

    Classloader 有3个作用 将class加载到JVM中去 审查每个类由谁去加载,是一种父优先的等级加载 把Class字节码统一编译成JVM统一要求的对象格式 ClassLoader的等级加载机 ...

  6. jvm(2):垃圾收集和内存分配

    typora-root-url: ./ 垃圾收集 垃圾收集器关注的是线程共享的这部分内存. jvisualvm用来监控JVM的运行情况,可以用它来查看和浏览Heap Dump.Thread Dump. ...

  7. 深入理解Java虚拟机二:垃圾收集与内存分配

    垃圾收集:垃圾收集要完成三件事,包括哪些内存需要回收,什么时候回收及如何回收. 1.需要回收的内存判定:没有引用指向原先分配给某个对象的内存时,则该内存是需要回收的垃圾 Java垃圾收集器在对内存进行 ...

  8. Java调优之jvm和线程的内存分析

    本文来源于铁木箱子的博客http://www.mzone.cc 这几天因为自己开发的一个网站在768M内存的机器上撑不起100多个用户的运行,因为每个用户启用功能后,系统将为每个用户分配8个左右的独立 ...

  9. 《深入理解java虚拟机》读书笔记——垃圾收集与内存分配策略

    可回收判定两种算法 引用计数法(Reference Counting):引用为0时可回收. 可达性分析法(Reachability Analysis): 从GCRoots对象到这个对象不可达. GCR ...

随机推荐

  1. Linux下的nexus数据迁移

    刚到公司没多久,目前公司有两个项目公用一个nexus的maven私服,现在想把两个私服的jar包拆分开: 我在原私服的nexus服务器中, 1.备份原nexus使用命令 完成tar包的压缩 打包完毕后 ...

  2. D3.js的v5版本入门教程(第十章)

    在这一章我们干点有趣的事——让我们上一章绘制的图表动起来,这样岂不是很有意思 为了让图表动起来,我们还是需要以下新的知识点 .attr(xxx) .transition() .attr(xxx),tr ...

  3. hypermesh对msh文件或者cas文件重新命名边界

    原视频下载地址: https://pan.baidu.com/s/1c1Thqm 密码: muhe

  4. #C++初学记录(奶酪#并查集)

    原题目:牛客网 题目描述 : 现有一块大奶酪,它的高度为 h,它的长度和宽度我们可以认为是无限大的,奶酪中间有许多半径相同的球形空洞.我们可以在这块奶酪中建立空间坐标系, 在坐标系中,奶酪的下表面为 ...

  5. mysql用户添加执行存储过程权限

  6. pip的安装

    1.get-pip.py安装 (官方)https://pip.pypa.io/en/stable/installing/#installing-with-get-pip-py $wget https: ...

  7. centos7 docker swarm加入集群失败

    提示的错误为 [root@localhost downloads]# docker swarm join --token SWMTKN-1-2ezr0k5ybds1la4vgi2z7j8ykxkmm0 ...

  8. matlab学习笔记10_5 通用字符串操作和比较函数

    一起来学matlab-matlab学习笔记10 10_5 通用字符串操作和比较函数 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考书籍 <matlab 程序设计与综合应用>张 ...

  9. (二)limit的高级用法

    一.取出前n条数据 ; 二.取出第几行到第几行的数据 ,; 解释:取出从第3行(从0行开始)开始的5条记录.

  10. CSS製作動畫效果(Transition、Animation、Transform)

    CSS 2D Transforms https://www.w3schools.com/css/css3_2dtransforms.asp CSS 3D Transforms https://www. ...