关于缓存行填充的一点思考

1.此文是记录我学习缓存行填充的一点思考,之前对缓存行填充只是有浅显的了解。
2.我不会从很基本的地方说起,这不是入门缓存行填充的文章。
3.看了很多关于缓存行的文章,但是很少去提及对象头是怎么缓存的,很疑惑。

我们要明白,缓存行填充主要解决的是伪共享(false sharing)问题。而64位OS一般缓存行是64字节(最常用),因此为了解决伪共享问题,我们采用缓存行填充的方式使缓存值的大小为64字节。

简单说一下Java6、Java7、Java8的处理方式,然后在利用Disruptor中的缓存填充做一下分析吧。

Java6的处理方式
// 64位OS,对象头本身有16字节,
public final static class FillLong { 
        public volatile long value = 0L;    // 8字节
        public long p1, p2, p3, p4, p5;    // 40字节
}
// 对象头本身有8字节,
public final static class FillLong { 
        public volatile long value = 0L;    // 8字节
        public long p1, p2, p3, p4, p5, p6;    // 48字节
}  

通过上面的方式可以减少出现伪共享的概率,但是不能绝对保证,原因一会Disruptor的填充方式。

Java7的处理方式
// 64位OS,对象头本身有16字节
public final static class FillLPadding { 
        public long p1, p2, p3, p4, p5;    // 40字节
}
public final static class FillLong { 
        public volatile long value = 0L;    // 8字节
} 
// 32位OS,对象头本身有8字节
public final static class FillLPadding { 
        public long p1, p2, p3, p4, p5;    // 48字节
}
public final static class FillLong { 
        public volatile long value = 0L;    // 8字节
} 

Java7会优化掉无用的字段,所以采用继承的方式填充对象。依据JVM对象继承中父类属性与子类属性关系,内存地址会连续排列布局的原因。这样可以防止Java7的优化。

Java8的处理方式,采用注解
@Contended
public final static class FillLong { 
        public volatile long value = 0L;    // 8字节
} 

在JDK1.8中,新增注解@sun.misc.Contended,来使各个变量在Cache line中分隔开。注意,jvm需要添加参数-XX:-RestrictContended才能开启此功能。

最后在看看Disruptor中防止伪共享的方式。

这种方式可以保证不会出现伪共享,可能是作者基于Java7编写的框架,没有用到注解,上代码:


class LhsPadding
{
    protected long p1, p2, p3, p4, p5, p6, p7;
}
class Value extends LhsPadding
{
    protected volatile long value;
}
class RhsPadding extends Value
{
    protected long p9, p10, p11, p12, p13, p14, p15;
}

这种将Value放在中间的方式,可以保证任何时候都不会出现伪共享。
顺便提一点,数组在内存中是连续存储的,结合预读性原理来看的话,缓存填充的方案是可以放在数组元素出现伪共享的。

<think>嗯,用户的问题是关于如何在Windows操作系统中清除ARP缓存表。首先,我需要确认用户的需求。用户可能遇到了网络问题,比如IP地址冲突或者MAC地址变更,需要清除ARP缓存来解决连接问题。根据引用[1]的内容,Windows下使用命令"arp -d"可以清除缓存,但需要具体说明使用方法。 接下来,我得回忆Windows和Linux在清除ARP缓存上的区别。引用中提到,Linux必须指定IP地址才能删除单个条目,而Windows可以不指定IP直接清除所有缓存。这一点很重要,因为用户可能误以为两个系统操作相同,导致命令执行失败。需要明确说明Windows的两种方法:清除单个条目和清除整个缓存。 然后,思考用户可能的操作场景。普通用户可能更倾向于使用图形界面,但技术用户可能偏好命令提示符。因此,应该同时提供命令行和图形界面的方法。对于命令行,要详细说明"arp -d"的具体用法,包括使用管理员权限的必要性。对于图形界面,需要指导用户如何通过设备管理器刷新ARP缓存,虽然步骤稍复杂,但适合不熟悉命令的用户。 另外,用户可能不清楚清除缓存后的效果,需要补充说明操作后的变化,比如短暂延迟或需要重新通信。还要考虑用户权限问题,强调以管理员身份运行命令提示符的重要性,避免权限不足导致失败。 最后,生成相关问题时要覆盖扩展内容,比如ARP缓存的作用、清除时机、不同系统对比以及故障排除。这些问题能帮助用户深入理解ARP机制,并解决潜在的网络问题。确保回答结构清晰,分步骤讲解,避免使用专业术语过多,让不同技术水平的用户都能理解。</think>好的,在 Windows 操作系统中清除 ARP 缓存表可以通过以下两种主要方法实现: ## 方法一:使用命令提示符 (推荐) 这是最常用和直接的方法。 1. **以管理员身份打开命令提示符:** * 按下 `Win + S` 键打开搜索。 * 输入 `cmd`。 * 在搜索结果“命令提示符”上**右键单击**。 * 选择“**以管理员身份运行**”。 (这是关键步骤,否则清除命令可能因权限不足而失败) * 如果出现用户帐户控制 (UAC) 提示,请点击“是”。 2. **执行清除命令:** * **清除整个 ARP 缓存:** 在打开的命令提示符窗口中输入以下命令,然后按回车: ```batch arp -d ``` 如果成功,通常不会有任何输出提示,或者可能显示“`OK`”。[^1] * **清除特定 IP 地址的 ARP 缓存条目:** 如果你只想清除某个特定 IP 地址 (例如 `192.168.1.100`) 的缓存条目,使用命令: ```batch arp -d 192.168.1.100 ``` 将 `192.168.1.100` 替换为你要清除的实际 IP 地址。如果成功删除,命令提示符通常会显示该 IP 地址对应的条目信息(表示它已被删除)或显示“`OK`”。 ## 方法二:通过禁用/启用网络适配器 (图形界面) 这种方法会重置适配器的网络连接状态,同时也会清除其 ARP 缓存。 1. **打开网络连接设置:** * 按下 `Win + R` 键打开“运行”对话框。 * 输入 `ncpa.cpl` 并按回车。 2. **选择网络适配器:** 在“网络连接”窗口中,找到你当前正在使用的网络适配器(例如“以太网”或“Wi-Fi”)。 3. **禁用适配器:** * **右键单击**该适配器。 * 选择“**禁用**”。 4. **启用适配器:** * 等待几秒钟。 * 再次**右键单击**该适配器。 * 选择“**启用**”。 ## 重要说明 * **权限:** 使用方法一(命令行)时,**必须**以管理员身份运行命令提示符 (`arp -d` 需要管理员权限才能成功执行)。 * **效果:** 清除 ARP 缓存后,系统会立即丢弃缓存的 IP-MAC 映射。当需要与这些 IP 地址通信时,系统会重新广播 ARP 请求来获取最新的 MAC 地址。这可能会导致短暂的网络延迟(通常非常短暂)。 * **临时性:** ARP 缓存是动态的,系统会根据通信情况自动重新学习和填充缓存。清除操作只影响当前缓存的条目。 * **Windows vs Linux:** 正如引用中提到的,Windows 的 `arp -d` 命令在不指定 IP 地址时可以清除所有缓存条目,这是它与 Linux 实现的一个关键区别(在 Linux 中 `arp -d` 必须指定 IP 地址才能删除单个条目)[^1]。 ## 总结 在 Windows 中清除整个 ARP 缓存表的最快捷有效方法是:**以管理员身份打开命令提示符,然后执行命令 `arp -d`**。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值