Java垃圾回收手册翻译 - 什么是垃圾回收

Java垃圾回收手册翻译 - 什么是垃圾回收

初看之下,垃圾回收应该要做其名称之事 - 找到和丢掉垃圾。然而事实上它正好做着相反的事,垃圾回收会记录所有仍在使用中的对象,然后将其他标记为垃圾。谨记这点,我们开始挖掘更多Java虚拟机如何实现被称为垃圾回收的自动化内存回收过程的细节。

为了避免一头扎进细节,我们从头开始,解释垃圾回收的一般性质以及核心概念和方法。

免责声明:本手册关注于Oracle Hotspot和OpenJDK的表现,其他运行时甚至其他虚拟机,比如jRockit或IBM J9,会在某些方面有不同于本手册所涵盖的表现。

手动内存管理

在开始现代形式的垃圾回收内容之前,我们先快速回顾一下那些需要手动显示分配和释放数据内存的日子。那时候如果你忘记释放内存,你将不能重用那块内存。这部分内存会被声明到但是没有使用,这种场景叫做内存泄漏。

下面是一个用C语言写的使用手动内存管理的简单例子:

int send_request() {
    size_t n = read_size();
    int *elements = malloc(n * sizeof(int));

    if(read_elements(n, elements) < n) {
        // elements not freed!
        return -1;
    }

    // …

    free(elements)
    return 0;
}

正如我们所见,非常容易忘记释放内存。相比于现在,内存泄漏在过去是更加常见的问题。你只能通过修复代码才能真正的对付它们。因此,一个更好的方法是将回收不用的内存的工作自动化,整体消除可能产生的人为错误。这个自动化操作叫做垃圾回收(简称GC)。

智能指针

一种自动化操作的方式是通过使用析构函数。例如,我们使用C++中的向量vector做上一个例子中同样的事,它会在离开其作用域时自动的调用其析构函数:

int send_request() {
    size_t n = read_size();
    vector<int> elements = vector<int>(n);

    if(read_elements(elements.size(), &elements[0]) < n) {
        return -1;
    }

    return 0;
}

但是再更复杂的情况中,尤其是在多个线程中共享对象时,仅仅使用析构函数并不够。这就引出了垃圾回收最简单的形式:引用计数。对每个对象,你只需要知道它有多少次被引用到,并且当这个计数达到零时这个对象就可以安全的被回收。一个众所周知的例子是C++中的共享指针shared pointers

int send_request() {
    size_t n = read_size();
    auto elements = make_shared<vector<int>>();

    // read elements

    store_in_cache(elements);

    // process elements further

    return 0;
}

现在,为了避免下次函数调用时再去读这个元素elements,我们可能想要缓存他们。在这个例子中,就不能再当向量vector离开作用域时销毁它。因此,我们使用共享指针shared_ptr,它记录引用到它的数量,当你使用它传值时计数增加,同时当它离开作用域时计数减少。一旦引用的计数降到零,共享指针shared_ptr就会自动地删除下面的向量。

TBC...

原文地址:https://www.cnblogs.com/pyx0/p/9222356.html

时间: 2024-11-03 16:24:35

Java垃圾回收手册翻译 - 什么是垃圾回收的相关文章

Java性能优化之JVM GC(垃圾回收机制)

Java的性能优化,整理出一篇文章,供以后温故知新. JVM GC(垃圾回收机制) 在学习Java GC 之前,我们需要记住一个单词:stop-the-world .它会在任何一种GC算法中发生.stop-the-world 意味着JVM因为需要执行GC而停止了应用程序的执行.当stop-the-world 发生时,除GC所需的线程外,所有的线程都进入等待状态,直到GC任务完成.GC优化很多时候就是减少stop-the-world 的发生. JVM GC回收哪个区域内的垃圾? 需要注意的是,JV

垃圾回收器如何确定哪些对象要回收---《深入理解java虚拟机》

垃圾回收器如何确定哪些对象要回收: 引用计数法 很多教科书判断对象是否存活的算法是这样的:给对象添加一个引用计数器,每当有一个地发引用它时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器都为0的对象就是不可能再被使用的. 客观地说,引用技术算法的实现简单,判定效率也很高,在大部分情况下它都是一个不错的算法,也有一些比较著名的应用案例,例如微软的COM技术.使用ActionScript 3 的FlashPlayer.Python语言以及在游戏脚本领域中被广泛应用的Squirrel中都

java虚拟机学习-JVM调优总结-垃圾回收面临的问题(8)

如何区分垃圾 上面说到的“引用计数”法,通过统计控制生成对象和删除对象时的引用数来判断.垃圾回收程序收集计数为0的对象即可.但是这种方法无法解决循环引用.所以,后来实现的垃圾判断算法中,都是从程序运行的根节点出发,遍历整个对象引用,查找存活的对象.那么在这种方式的实现中,垃圾回收从哪儿开始的呢?即,从哪儿开始查找哪些对象是正在被当前系统使用的.上面分析的堆和栈的区别,其中栈是真正进行程序执行地方,所以要获取哪些对象正在被使用,则需要从Java栈开始.同时,一个栈是与一个线程对应的,因此,如果有多

Java GC 垃圾回收(二)之 判断那些可回收,怎么回收

1.哪些对象可回收? 可行性分析算法 通过一系列GC Roots(?1)作为起始点,其到对象之间的引用(?2)称为引用链,当对象到GC Roots之间不存在引用链相连, 则此对象是不可用的.如下,Object5,Object6,Object7被判定为可回收对象. 2.怎么回收? 3.方法区回收: a.废弃常量: 没有任何String对象引用常量池的常量,也没有其他地方引用这个常量. b.无用的类: 下列条件全部满足: 1.该类所有的实例都已经被回收. 2.加载改类的ClassLoader已经被回

【转载】Java性能优化之JVM GC(垃圾回收机制)

章来源:https://zhuanlan.zhihu.com/p/25539690 Java的性能优化,整理出一篇文章,供以后温故知新. JVM GC(垃圾回收机制) 在学习Java GC 之前,我们需要记住一个单词:stop-the-world .它会在任何一种GC算法中发生.stop-the-world 意味着JVM因为需要执行GC而停止了应用程序的执行.当stop-the-world 发生时,除GC所需的线程外,所有的线程都进入等待状态,直到GC任务完成.GC优化很多时候就是减少stop-

Java实现类的重载及使用垃圾回收钩子函数

下面以代码加注释,来方便读者理解. package com.company; public class Main { public static void main(String[] args) { // 未被引用的,无用对象 new Book("hello Java"); // 手动调用系统回收进行标记,进行回收 System.gc(); } } //声明一个书类 class Book { // 书的名称 String bookName; // 书的价格 double bookPri

Java GC系列(3):垃圾回收器种类

本文由 ImportNew - 好好先生 翻译自 javapapers. 目录 垃圾回收介绍 垃圾回收是如何工作的? 垃圾回收的类别 垃圾回收监视和分析 在这篇教程中我们将学习几种现有的垃圾回收器.在Java中,垃圾回收是一个自动的进程可以替代程序员进行内存的分配与回收这些复杂的工作.这篇是垃圾回 收教程系列的第三篇,在前面的第2部分我们看到了在Java中垃圾回收是如何工作的,那是篇有意思的文章,我推荐你去看一下.第一部分介绍了Java的垃 圾回收,主要有JVM体系结构,堆内存模型和一些Java

[Think In Java]基础拾遗1 - 对象初始化、垃圾回收器、继承、组合、代理、接口、抽象类

目录 第一章 对象导论第二章 一切都是对象第三章 操作符第四章 控制执行流程第五章 初始化与清理第六章 访问权限控制第七章 复用类第九章 接口 第一章 对象导论 1. 对象的数据位于何处? 有两种方式在内存中存放对象: (1)为了追求最大的执行速度,对象的存储空间和生命周期可以在编写程序时确定,这可以通过将对象置于堆栈或者静态存储区域内来实现.这种方式牺牲了灵活性. (2)在被称为堆的内存池中动态地创建对象.在这种方式,知道运行时才知道对象需要多少对象,它们的生命周期如何,以及它们的具体类型.

java学习笔记4--对象的初始化与回收

1.对象初始化和回收 对象初始化 系统在生成对象时,会为对象分配内存空间,并自动调用构造方法对实例变量进行初始化 对象回收 对象不再使用时,系统会调用垃圾回收程序将其占用的内存回收 构造方法 一种和类同名的特殊方法 用来初始化对象 Java中的每个类都有构造方法,用来初始化该类的一个新的对象 没有定义构造方法的类,系统自动提供默认的构造方法 构造方法的特点 方法名与类名相同 没有返回类型,修饰符void也不能有 通常被声明为公有的(public) 可以有任意多个参数 主要作用是完成对象的初始化工