前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >WeakHashMap理解

WeakHashMap理解

作者头像
全栈程序员站长
发布于 2022-09-04 05:17:40
发布于 2022-09-04 05:17:40
53400
代码可运行
举报
运行总次数:0
代码可运行

大家好,又见面了,我是你们的朋友全栈君。

一、什么是WeakHashMap?

从名字可以得知主要和Map有关,不过还有一个Weak,我们就更能自然而然的想到这里面还牵扯到一种弱引用结构,因此想要彻底搞懂,我们还需要知道四种引用。如果你已经知道了,可以跳过。

1、四种引用

在jvm中,一个对象如果不再被使用就会被当做垃圾给回收掉,判断一个对象是否是垃圾,通常有两种方法:引用计数法和可达性分析法。不管是哪一种方法判断一个对象是否是垃圾的条件总是一个对象的引用是都没有了。

JDK.1.2 之后,Java 对引用的概念进行了扩充,将引用分为了:强引用、软引用、弱引用、虚引用4 种。而我们的WeakHashMap就是基于弱引用。

(1)强引用

如果一个对象具有强引用,它就不会被垃圾回收器回收。即使当前内存空间不足,JVM也不会回收它,而是抛出 OutOfMemoryError 错误,使程序异常终止。比如String str = “hello”这时候str就是一个强引用。

(2)软引用

内存足够的时候,软引用对象不会被回收,只有在内存不足时,系统则会回收软引用对象,如果回收了软引用对象之后仍然没有足够的内存,才会抛出内存溢出异常。

(3)弱引用

如果一个对象具有弱引用,在垃圾回收时候,一旦发现弱引用对象,无论当前内存空间是否充足,都会将弱引用回收。

(4)虚引用

如果一个对象具有虚引用,就相当于没有引用,在任何时候都有可能被回收。使用虚引用的目的就是为了得知对象被GC的时机,所以可以利用虚引用来进行销毁前的一些操作,比如说资源释放等。

我们的WeakHashMap是基于弱引用的,也就是说只要垃圾回收机制一开启,就直接开始了扫荡,看见了就清除。

二、为什么需要WeakHashMap

WeakHashMap正是由于使用的是弱引用,因此它的对象可能被随时回收。更直观的说,当使用 WeakHashMap 时,即使没有删除任何元素,它的尺寸、get方法也可能不一样。比如:

(1)调用两次size()方法返回不同的值;第一次为10,第二次就为8了。

(2)两次调用isEmpty()方法,第一次返回false,第二次返回true;

(3)两次调用containsKey()方法,第一次返回true,第二次返回false;

(4)两次调用get()方法,第一次返回一个value,第二次返回null;

是不是觉得有点恶心,这种飘忽不定的东西好像没什么用,试想一下,你准备使用WeakHashMap保存一些数据,写着写着都没了,那还保存个啥呀。

不过有一种场景,最喜欢这种飘忽不定、一言不合就删除的东西。那就是缓存。在缓存场景下,由于内存是有限的,不能缓存所有对象,因此就需要一定的删除机制,淘汰掉一些对象。

现在我们已经知道了WeakHashMap是基于弱引用,其对象可能随时被回收,适用于缓存的场景。下面我们就来看看,WeakHashMap是如何实现这些功能。

三、WeakHashMap工作原理

1、WeakHashMap为什么具有弱引用的特点:随时被回收对象

这个问题就比较简单了,我们的目的主要是验证。WeakHashMap是基于弱引用的,肯定就具有了弱引用的性质。我们去他的源码中看一下:

从这里我们可以看到其内部的Entry继承了WeakReference,也就是弱引用,所以就具有了弱引用的特点。不过还要注意一点,那就是ReferenceQueue,他的作用是GC会清理掉对象之后,引用对象会被放到ReferenceQueue中。

2、WeakHashMap中的Entry被GC后,WeakHashMap是如何将其移除的?

意思是某一个Entry突然被垃圾回收了,这之后WeakHashMap肯定就不能保留这个Entry了,那他是如何将其移除的呢?

WeakHashMap内部有一个expungeStaleEntries函数,在这个函数内部实现移除其内部不用的entry从而达到的自动释放内存的目的。因此我们每次访问WeakHashMap的时候,都会调用这个expungeStaleEntries函数清理一遍。这也就是为什么前两次调用WeakHashMap的size()方法有可能不一样的原因。我们可以看看是如何实现的:

首先GC每次清理掉一个对象之后,引用对象会被放到ReferenceQueue中。然后遍历这个queue进行删除即可。

当然。WeakHashMap的增删改查操作都会直接或者间接的调用expungeStaleEntries()方法,达到及时清除过期entry的目的。

四、WeakHashMap的关键实现

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private static class Entry<K,V> extends WeakReference<Object> implements Map.Entry<K,V>

Entry继承自WeakReference(弱引用),那么Entry本身就是一个弱引用。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    Entry(Object key, V value,
          ReferenceQueue<Object> queue,
          int hash, Entry<K,V> next) {
        super(key, queue);
        this.value = value;
        this.hash  = hash;
        this.next  = next;
    }

从Entry的构造函数中可以看出:Entry通过传入key和queue调用了父类WeakReference的构造函数,那么key就成为了这个弱引用所引用的对象,并把这个弱引用注册到了引用队列上。

image.png

如果一个对象只具有弱引用,那就类似于可有可无的生活用品。只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程, 因此不一定会很快发现那些只具有弱引用的对象。 弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。

因为存储在Entry中的key只具有弱引用,所以并不能阻止垃圾回收线程对它进行回收,当发生垃圾回收时,Entry中的key被回收,java虚拟机就会把这个Entry添加到与之关联的queue中去。

通过上面的分析,存储在WeakHashMap中的key随时都会面临被回收的风险,因此每次查询WeakHashMap时,都要确认当前WeakHashMap是否已经有key被回收了。当key被回收时,引用这个key的Entry对象就会被添加到引用队列中去,所以只要查询引用队列是否有Entry对象,就可以确认是否有key被回收了。WeakHashMap通过调用expungeStaleEntries方法来清除已经被回收的key所关联的Entry对象。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private void expungeStaleEntries() {
    for (Object x; (x = queue.poll()) != null; ) {
        synchronized (queue) {
            @SuppressWarnings("unchecked")
                Entry<K,V> e = (Entry<K,V>) x;
            int i = indexFor(e.hash, table.length);

            Entry<K,V> prev = table[i];
            Entry<K,V> p = prev;
            while (p != null) {
                Entry<K,V> next = p.next;
                if (p == e) {
                    if (prev == e)
                        table[i] = next;
                    else
                        prev.next = next;
                    // Must not null out e.next;
                    // stale entries may be in use by a HashIterator
                    e.value = null; // Help GC
                    size--;
                    break;
                }
                prev = p;
                p = next;
            }
        }
    }
}

WeakHashMap在调用putget方法之前,都会调用expungeStaleEntries方法来清除已经被回收的key所关联的Entry对象。因为Entry是弱引用,即使引用着key对象,但是依然不能阻止垃圾回收线程对key对象的回收。

如果存放在WeakHashMap中的key都存在强引用,那么WeakHashMap就会退化成HashMap。如果在系统中希望通过WeakHashMap自动清除数据,请尽量不要在系统的其他地方强引用WeakHashMap的key,否则,这些key就不会被回收,WeakHashMap也就无法正常释放它们所占用的表项。

五、案例应用

如果在一个普通的HashMap中存储一些比较大的值如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Map<Integer,Object> map = new HashMap<>();
for(int i=0;i<10000;i++)
{
    Integer ii = new Integer(i);
    map.put(ii, new byte[i]);
}

运行参数:-Xmx5M 运行结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at collections.WeakHashMapTest.main(WeakHashMapTest.java:39)

如果我们将HashMap换成WeakHashMap其余都不变:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Map<Integer,Object> map = new WeakHashMap<>();
for(int i=0;i<10000;i++)
{
    Integer ii = new Integer(i);
    map.put(ii, new byte[i]);
}

运行结果:(无任何报错)

这两段代码比较可以看到WeakHashMap的功效,如果在系统中需要一张很大的Map表,Map中的表项作为缓存使用,这也意味着即使没能从该Map中取得相应的数据,系统也可以通过候选方案获取这些数据。虽然这样会消耗更多的时间,但是不影响系统的正常运行。

在这种场景下,使用WeakHashMap是最合适的。因为WeakHashMap会在系统内存范围内,保存所有表项,而一旦内存不够,在GC时,没有被引用的表项又会很快被清除掉,从而避免系统内存溢出。

我们这里稍微改变一下上面的代码(加了一个List):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Map<Integer,Object> map = new WeakHashMap<>();
List<Integer> list = new ArrayList<>();
for(int i=0;i<10000;i++)
{
    Integer ii = new Integer(i);
    list.add(ii);
    map.put(ii, new byte[i]);
}   

运行结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at collections.WeakHashMapTest.main(WeakHashMapTest.java:43)

如果存放在WeakHashMap中的key都存在强引用,那么WeakHashMap就会退化成HashMap。如果在系统中希望通过WeakHashMap自动清除数据,请尽量不要在系统的其他地方强引用WeakHashMap的key,否则,这些key就不会被回收,WeakHashMap也就无法正常释放它们所占用的表项。

要想WeakHashMap能够释放掉被回收的key关联的value对象,要尽可能的多调用下put/size/get等操作,因为这些方法会调用expungeStaleEntries方法,expungeStaleEntries方法是关键,而如果不操作WeakHashMap,以企图WeakHashMap“自动”释放内存是不可取的,这里的“自动”是指譬如:map.put(obj, new byte[10M]);之后obj=null了,之后再也没调用过map的任何方法,那么new出来的10M空间是不会释放的。

注意

WeakHashMap的key可以为null,那么当put一个key为null,value为一个很大对象的时候,这个很大的对象怎么采用WeakHashMap的自带功能自动释放呢?

代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Map<Object,Object> map = new WeakHashMap<>();
map.put(null,new byte[5*1024*928]);
int i = 1;
while(true)
{
    System.out.println();
    TimeUnit.SECONDS.sleep(2);
    System.out.println(map.size());
    System.gc();
    System.out.println("==================第"+i+++"次GC结束====================");
}

运行参数:-Xmx5M -XX:+PrintGCDetails 运行结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1
[GC [PSYoungGen: 680K->504K(2560K)] 5320K->5240K(7680K), 0.0035741 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC [PSYoungGen: 504K->403K(2560K)] [ParOldGen: 4736K->4719K(5120K)] 5240K->5123K(7680K) [PSPermGen: 2518K->2517K(21504K)], 0.0254473 secs] [Times: user=0.06 sys=0.00, real=0.03 secs] 
==================1GC结束====================

1
[Full GC [PSYoungGen: 526K->0K(2560K)] [ParOldGen: 4719K->5112K(5120K)] 5246K->5112K(7680K) [PSPermGen: 2520K->2520K(21504K)], 0.0172785 secs] [Times: user=0.01 sys=0.00, real=0.02 secs] 
==================2GC结束====================

1
[Full GC [PSYoungGen: 41K->0K(2560K)] [ParOldGen: 5112K->5112K(5120K)] 5153K->5112K(7680K) [PSPermGen: 2520K->2520K(21504K)], 0.0178421 secs] [Times: user=0.03 sys=0.00, real=0.02 secs] 
==================3GC结束====================

1
[Full GC [PSYoungGen: 41K->0K(2560K)] [ParOldGen: 5112K->5112K(5120K)] 5153K->5112K(7680K) [PSPermGen: 2520K->2520K(21504K)], 0.0164874 secs] [Times: user=0.01 sys=0.00, real=0.02 secs] 
==================4GC结束====================

1
[Full GC [PSYoungGen: 41K->0K(2560K)] [ParOldGen: 5112K->5112K(5120K)] 5153K->5112K(7680K) [PSPermGen: 2520K->2520K(21504K)], 0.0191096 secs] [Times: user=0.05 sys=0.00, real=0.02 secs] 
==================5GC结束====================
(一直循环下去)

可以看到在map.put(null, new byte[5*1024*928]);之后,相应的内存一直没有得到释放。

通过显式的调用map.remove(null)可以将内存释放掉,如下代码所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Map<Integer,Object> map = new WeakHashMap<>();
System.gc();
System.out.println("===========gc:1=============");
map.put(null,new byte[4*1024*1024]);
TimeUnit.SECONDS.sleep(5);
System.gc();
System.out.println("===========gc:2=============");
TimeUnit.SECONDS.sleep(5);
System.gc();
System.out.println("===========gc:3=============");
map.remove(null);
TimeUnit.SECONDS.sleep(5);
System.gc();
System.out.println("===========gc:4=============");

运行参数:-Xmx5M -XX:+PrintGCDetails 运行结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[GC [PSYoungGen: 720K->504K(2560K)] 720K->544K(6144K), 0.0023652 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC [PSYoungGen: 504K->0K(2560K)] [ParOldGen: 40K->480K(3584K)] 544K->480K(6144K) [PSPermGen: 2486K->2485K(21504K)], 0.0198023 secs] [Times: user=0.11 sys=0.00, real=0.02 secs] 
===========gc:1=============
[GC [PSYoungGen: 123K->32K(2560K)] 4699K->4608K(7680K), 0.0026722 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC [PSYoungGen: 32K->0K(2560K)] [ParOldGen: 4576K->4578K(5120K)] 4608K->4578K(7680K) [PSPermGen: 2519K->2519K(21504K)], 0.0145734 secs] [Times: user=0.03 sys=0.00, real=0.01 secs] 
===========gc:2=============
[GC [PSYoungGen: 40K->32K(2560K)] 4619K->4610K(7680K), 0.0013068 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC [PSYoungGen: 32K->0K(2560K)] [ParOldGen: 4578K->4568K(5120K)] 4610K->4568K(7680K) [PSPermGen: 2519K->2519K(21504K)], 0.0189642 secs] [Times: user=0.06 sys=0.00, real=0.02 secs] 
===========gc:3=============
[GC [PSYoungGen: 40K->32K(2560K)] 4609K->4600K(7680K), 0.0011742 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC [PSYoungGen: 32K->0K(2560K)] [ParOldGen: 4568K->472K(5120K)] 4600K->472K(7680K) [PSPermGen: 2519K->2519K(21504K)], 0.0175907 secs] [Times: user=0.02 sys=0.00, real=0.02 secs] 
===========gc:4=============
Heap
 PSYoungGen      total 2560K, used 82K [0x00000000ffd00000, 0x0000000100000000, 0x0000000100000000)
  eden space 2048K, 4% used [0x00000000ffd00000,0x00000000ffd14820,0x00000000fff00000)
  from space 512K, 0% used [0x00000000fff80000,0x00000000fff80000,0x0000000100000000)
  to   space 512K, 0% used [0x00000000fff00000,0x00000000fff00000,0x00000000fff80000)
 ParOldGen       total 5120K, used 472K [0x00000000ff800000, 0x00000000ffd00000, 0x00000000ffd00000)
  object space 5120K, 9% used [0x00000000ff800000,0x00000000ff876128,0x00000000ffd00000)
 PSPermGen       total 21504K, used 2526K [0x00000000fa600000, 0x00000000fbb00000, 0x00000000ff800000)
  object space 21504K, 11% used [0x00000000fa600000,0x00000000fa8778f8,0x00000000fbb00000)

分析:

1、在WeakHashMap中,put的key为null时,放入的是NULL_KEY,即:private static final Object NULL_KEY = new Object(),是一个静态常量。 2、在WeakHashMap中,由于传给WeakReference的只有key和queue,即gc只回收里面的KEY,而不会动value,value的清除则是在expungeStaleEntries这个私有方法进行的。 3、而static的就不在gc之列,所以key也就不会被gc,所以它的大值value,也就不会被设为null,不会被回收。 4、通过调用remove方法,最终table[k]设为null,此时大对象游离所以被回收。

只有通过remove方法才能删除null键所关联的value,建议在使用WeakHashMap的时候尽量避免使用null作为键。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/138148.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年5月3,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
RHEL构建DNS服务器-多区域
前言 <沿用单区域配置> DNS服务器信息: 操作系统版本:RHEL 6.5 (VMware 11 For Linux) 服务器IP地址:192.168.4.7 服务器主机名:dns.lianst.com 负责解析区域:lianst.com,baidu.com 客户端信息: 操作系统版本:RHEL 6.5 (VMware 11 For Linux) 客户端IP地址:192.168.4.6 客户机主机名:pxe.lianst.com 实现如下查询: 能够解析lianst.com(
行 者
2018/03/26
1.8K0
RHEL构建DNS服务器-多区域
DNS服务器搭建(Linux版本)
参考视频:P2.Linux服务器项目实训-DNS服务器配置(bind的正向解释和反向解释)
宝耶需努力
2022/12/13
4K0
DNS服务器搭建(Linux版本)
Linux服务配置 DNS服务器配置「建议收藏」
DNS(Domain Name System):域名系统 用于IP和域名的解析 产生原因:上网需要IP,而IP不好记忆,用英文字母表示的域名便于记忆。
全栈程序员站长
2022/09/05
15.2K0
Linux 中搭建 主从dns域名解析服务器
主从(Master-Slave)DNS架构是一种用于提高DNS系统可靠性和性能的配置方式。
神秘泣男子
2024/06/03
1K0
Linux 中搭建 主从dns域名解析服务器
DNS从入门到管理(一)
DNS概述 DNS(Domain Name System,域名系统),域名和IP地址相互映射的一个分布式数据库,通过主机名,最终得到该主机名对应的IP地址的过程叫做域名解析。而DNS的主要作用,就是域名解析,将主机名解析成IP地址。DNS这种机制能够完成从域名(FQDN)到主机识别IP地址之间的转换,在DNS诞生之前,这个功能主要是通过本地的一个hosts文件来记录域名和IP的对应关系,但hosts文件只能作用于本机,不能同步更新至所有主机,且当hosts文件很庞大时难以管理,因此,一个分布式、分层次的主机
小小科
2018/05/04
2.4K0
DNS从入门到管理(一)
内网搭建DNS服务器
组织域:.com, .org, .net, .mil, .edu, .gov, .info, .cc, .me, .tv
小陈运维
2021/12/23
8K0
RHEL构建DNS服务器-单区域
前言 DNS服务器信息: 操作系统版本:RHEL 6.5 (VMware 11 For Linux) 服务器IP地址:192.168.4.7 服务器主机名:dns.lianst.com 负责解析区域:lianst.com 客户端信息: 操作系统版本:RHEL 6.5 (VMware 11 For Linux) 客户端IP地址:192.168.4.6 客户机主机名:pxe.lianst.com 一、准备工作 1.修改主机名 2.关闭防火墙(iptables/SELINUX) 3
行 者
2018/03/26
1.3K0
RHEL构建DNS服务器-单区域
DNS原理和CentOS7上bind域名服务器配置详解
1、什么是DNS? ( Domain Name System)是“域名系统”的英文缩写,是一种组织成域层次结构的计算机和网络服务命名系统,它用于TCP/IP网络,它所提供的服务是用来将主机名和域名转换为IP地址的工作。DNS就是这样的一位“翻译官”,它的基本工作原理可用下图来表示。
kirin
2020/09/07
3.5K0
DNS原理和CentOS7上bind域名服务器配置详解
DNS服务器搭建与配置
DNS(Domain Name System–域名系统),是因特网的一项服务。它作为将域名和IP地址相互映射的一个分布式数据库,能够使人更方便地访问互联网。是一个应用层的协议DNS使用TCP和UDP端口53。
全栈程序员站长
2022/09/05
5.3K0
CentOS 7.4搭建DNS服务器
DNS(Domain Name System,域名系统),互联网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住较难记住的IP地址。通过域名,最终得到该域名对应的IP地址的过程叫做域名解析(或主机名解析)。
子润先生
2021/07/09
2.9K0
Centos7服务器运维服务系统安装过程中遇到的问题总结
由于我们Sinesafe的客户要求网站的服务器要装Centos7版本所以给大家分享下安装的过程与经验,如果需要深入的服务器运维服务也可以找我们。
网站安全专家
2019/07/24
1.1K0
Centos7服务器运维服务系统安装过程中遇到的问题总结
CentOS 7.4搭建DNS服务器实现主从同步
第一步:准备工作 systemctl stop firewalld //关闭防火墙 setenforce 0 //关闭selinux yum install bind //安装DNS服务
星哥玩云
2022/07/25
1.4K0
CentOS 7.4搭建DNS服务器实现主从同步
DNS:使用 bind9 配置主从权威DNS服务器
对每个人而言,真正的职责只有一个:找到自我。然后在心中坚守其一生,全心全意,永不停息。所有其它的路都是不完整的,是人的逃避方式,是对大众理想的懦弱回归,是随波逐流,是对内心的恐惧 ——赫尔曼·黑塞《德米安》
山河已无恙
2023/08/21
8030
DNS:使用 bind9 配置主从权威DNS服务器
自建DNS解析服务器
搭建DNS解析服务器,不是属于DNS服务器:比如114.114.114.114啥的,而是能够帮你解析域名的服务器。
幻影龙王
2021/09/05
19.2K0
自建DNS解析服务器
CentOS 7下简单搭建DNS服务器
  DNS(Domain Name System)域名系统协议,作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用挨个记住IP地址。通过主机名,最终得到该主机名对应的IP地址的过程叫做域名解析(或主机名解析)。DNS协议号是udp53。DNS服务器的作用就是就好比通讯录一样,为各种网络程序找到对应目标主机的IP地址或对应的主机域名。每个IP地址都可以有一个主机名,主机名由一个或多个字符串组成,字符串之间用小数点隔开。有了主机名,就不要死记硬背每台IP设备的IP地址,只要记住相对直观有意义的主机名就行了。这就是DNS协议所要完成的功能。
星哥玩云
2022/07/31
3.1K0
Linux中搭建DNS 域名解析服务器(详细版)
正向查询用于将域名解析为IP地址,这样用户就可以使用易记的域名来访问互联网上的各种网络资源,而不需要记忆IP地址。
神秘泣男子
2024/06/03
1.5K0
Linux中搭建DNS 域名解析服务器(详细版)
「玩转Lighthouse」轻量应用服务器自建DNS解析服务器
最近买的几台轻量应用服务器,都不知道干啥用,干脆搭建属于自己的DNS解析服务器吧。
Balliol Chen
2022/04/23
4K0
Linux(RHEL7及CentOS7)下DNS服务器的搭建与配置
版权声明:本文为耕耘实录原创文章,各大自媒体平台同步更新。欢迎转载,转载请注明出处,谢谢。
耕耘实录
2018/12/20
3.3K0
CentOS 7 DNS服务器架设
要保证即能够解析内网域名linuxidc.local的解析,又能解析互联网的域名。
星哥玩云
2022/07/03
3.2K0
DNS主从服务器搭建
http://blog.51cto.com/yichenyang/1911098 http://blog.51cto.com/wubinary/1379595
三杯水Plus
2018/11/14
4.3K0
推荐阅读
相关推荐
RHEL构建DNS服务器-多区域
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档