JVM内存回收区域+对象存活的判断+引用类型+垃圾回收线程
此文已由作者赵计刚薪授权网易云社区发布。
欢迎访问网易云社区,了解更多网易技术产品运营经验。
注意:本文主要参考自《深入理解Java虚拟机(第二版)》
说明:查看本文之前,推荐先知道JVM内存结构,见《第一章 JVM内存结构》
1、内存回收的区域
堆:这是GC的主要区域
方法区:回收两样东西
无用的类
废弃的常量
栈和PC寄存器是线程私有区域,不发生GC
2、怎样判断对象是否存活
垃圾回收:回收掉死亡对象所占的内存。判断对象是否死亡,有两种方式:
引用计数法
每次为对象赋值时,都要进行计数器值的增减,消耗较大
对于A、B相互引用这种情况处理不了(这一点是不用的主要原因)
原理:给对象添加一个引用计数器,每当有一个地方引用它时,计数器值+1;引用失效时,计数器值-1
实际中不用,不用的两个原因
可达性分析(跟踪收集)
原理:从根集合(GC Roots)开始向下扫描,根集合中的节点可以到达的节点就是存活节点,根集合中的节点到达不了的节点就是将要被回收的死亡节点,如下图中的A/B/C是存活节点,D/E是死亡节点:
Java栈中的对象引用(存在于局部变量表中,注意:局部变量表中存放的是基本数据类型和对象引用)
方法区中:常量+静态(static)变量
传到本地方法中,还没有被本地方法释放的对象引用
这是垃圾回收最多考虑的地方,所以有时,我们也会将死亡对象称为"没有引用指向的对象"
根集合中的节点包括:简单来讲,就是全局性的引用(常量和静态属性)和栈引用(下边第一、三)
3、3种引用类型
强引用(Strong Reference):A a = new A();//a是强引用
软引用(Soft Reference):当内存不足时,释放软引用所引用的对象;当内存足够时,就是一个普通对象(强引用)
弱引用(Weak Reference):弱引用对象只能存活到下一次垃圾回收之前,一旦发生垃圾回收,立刻被回收掉
4、方法区的回收
废弃常量:例如,没有任何一个引用指向常量池中的"abc"字符串,则"abc"字符串被回收
无用的类:满足以下三个条件
Java堆中不存在该类的任何实例
加载该类的ClassLoader被回收
该类的Class对象没有在任何地方被引用
注意:
在实际开发中,尽量不用JSP去做前端,而是用velocity、freemarker这样的模板引擎去做
与类相关常用的三个参数:
-XX:+PrintClassHistogram:输出类统计状态
-XX:-TraceClassLoading:打印类加载信息
-XX:-TraceClassUnloading:打印类卸载信息
5、垃圾回收线程
系统的垃圾回收是由垃圾回收线程来检测操作的,该线程是一个后台线程(daemon thread)。
5.1、后台线程与我们使用的前台线程而言,有一个特点:当JVM中的前台线程数量为0时,后台线程自动消亡。可以这样讲,后台线程依托于前台线程而存在。
5.2、垃圾回收线程为什么要设置成为后台线程呢?
我们想一下,当前台一个线程都没有时,垃圾还会有吗?或者说垃圾回收还有必要吗?答案是没有必要,所以此时垃圾回收线程也就失去了存活的意义。
所以可以这样讲,将一个线程是否设置为后台线程,就看这条线程在没有其他线程存在的情况下,是否还有存活的意义。
例如,在我们使用Apache mina2做RPC时,我们在消息的接收端直接开启一个后台线程启动服务来接受消息发送端发来的消息事件请求就可以。试着去想,如果在整个JVM中只有当前的这一个后台线程了,那么这个线程还有必要存活下来吗?当然没有必要,因为消息永远都不会再发送了(前台线程都没了)
免费领取验证码、内容安全、短信发送、直播点播体验包及云服务器等套餐
更多网易技术、产品、运营经验分享请点击。
相关文章:
【推荐】 [翻译]pytest测试框架(一)
【推荐】 dubbo事件通知机制(1)
【推荐】 debian 7上源码编译MongoDB 3.4版本
JVM内存回收区域+对象存活的判断+引用类型+垃圾回收线程的更多相关文章
- 第三章 JVM内存回收区域+对象存活的判断+引用类型+垃圾回收线程
注意:本文主要参考自<深入理解Java虚拟机(第二版)> 说明:查看本文之前,推荐先知道JVM内存结构,见<第一章 JVM内存结构> 1.内存回收的区域 堆:这是GC的主要区域 ...
- 判断Java对象存活的算法、垃圾回收算法
判断Java对象存活的算法 一.引用计数算法 给对象添加一个引用计数器,每当一个地方引用它的时候就将计数器加1,当引用失效的时候就将计数器减1,任何时刻计数器为0的对象都不可再被使用.这种算法虽然简单 ...
- JVM(二) 对象存活判断和垃圾回收算法
对象的创建 概述 下面简要介绍创建对象的几个重要步骤 : 检查能否在常量池定位到一个类的符号引用,并检查这个符号代表的类是否已被加载,解析和初始化过.如果没有则执行类加载的操作.(即是说对象的引用放在 ...
- JVM内存各个区域分工简单介绍
JVM内存各个区域简单介绍: 程序计数器:程序计数器是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器. 在使用多线程时,为了线程切换后能恢复到正确的执行位置,每条线程都需要有个独立 ...
- java中对JVM的深度解析、调优工具、垃圾回收
jdk自带的JVM调优工具 jvm监控分析工具一般分为两类,一种是jdk自带的工具,一种是第三方的分析工具.jdk自带工具一般在jdk bin目录下面,以exe的形式直接点击就可以使用,其中包含分析工 ...
- 《垃圾回收的算法与实现》——Python垃圾回收
Python垃圾回收 python采用引用计数法进行垃圾回收 Python内存分配 python在分配内存空间时,在malloc之上堆放了3个独立的分层. python内存分配时主要由arena.po ...
- jvm内存结构及对象漫谈(较全)
最近想整理一下GC相关的知识和经验,在整理之前先整理一下jvm的内存结构,后续会持续更新. jvm内存结构重要由两部分组成:线程共享区域与线程私有区域,如下图所示: 其中方法区和堆为线程共享区域,栈与 ...
- 快速串讲——JVM内存的区域划分
目的 快速定位JVM内存泄漏或者溢出等问题. 面试基础题,加分项. 文章持续更新,微信搜索「万猫学社」第一时间阅读,关注后回复「电子书」,免费获取12本Java必读技术书籍. 程序计数器(Progra ...
- java内存区域,jvm内存各个区域详解
一.运行时数据区域 1.如图所示,可分为如下几个区域. 2.程序计数器 程序计数器是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器.字节码解释器工作时就是通过改变这个计数器的 ...
随机推荐
- 只有自己看的懂的vue 二叉树的3级联动
我是在vue做的数据 actions mutations state index页面获取值 传递给子页面 子页面的操作 <template> <div class='cascade_ ...
- Gitlab不小心关闭了sign-in,无法登录web的坑。。。
手贱一不小心用root在gitlab后台把登录功能给关了,当时我就懵逼了. 解决方法如下: #进入数据库修改配置[root@gitlab-server ~]# gitlab-psql gitlabhq ...
- [Selenium]Eclipse hangs at 57% in debug mode with TestNG tests
案例1: I am very thankful to saish and cbeust for the solution. I went through the similar issue with ...
- 百度词汇检索,计算PMI值
'''词汇检索百度返回值,并且计算PMI值的类''' from bs4 import BeautifulSoup import requests import re import pandas as ...
- 2018.09.25 bzoj1856: [Scoi2010]字符串(组合数学)
传送门 如果有n==m的条件就是卡特兰数. 但现在n不一定等于m. 我们可以考虑用求卡特兰数一样的方法来求答案. 我们知道有一种求卡特兰数的方法是转到二维平面求答案. 这道题就可以这样做. 我们将这个 ...
- 2018.09.25 poj2068 Nim(博弈论+dp)
传送门 题意简述:m个石子,有两个队每队n个人循环取,每个人每次取石子有数量限制,取最后一块的输,问先手能否获胜. 博弈论+dp. 我们令f[i][j]f[i][j]f[i][j]表示当前第i个人取石 ...
- 2018.08.04 bzoj3261: 最大异或和(trie)
传送门 简单可持久化01trie树. 实际上这东西跟可持久化线段树貌似是一个东西啊. 要维护题目给出的信息,就需要维护前缀异或和并且把它们插入一棵01trie树,然后利用贪心的思想在上面递归就行了,因 ...
- hdu-1129(模拟题)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1129 注意:c_code[i]=(p_code[i*k%n]-i)%28; #include<i ...
- Mysql字符串字段判断是否包含某个字符串的3种方法[转载]
方法一: SELECT * FROM users WHERE emails like "%b@email.com%"; 方法二: 利用mysql字符串函数 find_in_set( ...
- java NIO编程(转)
一.概念 在传统的java网络编程中,都是在服务端创建一个ServerSocket,然后为每一个客户端单独创建一个线程Thread分别处理各自的请求,由于对于CPU而言,线程的开销是很大的,无限创建线 ...