SEO教程

SEO教程

Products

当前位置:首页 > SEO教程 >

如何找到专业的网站设计师,以便在镇江地区接单?

96SEO 2026-02-23 15:37 12


使用危险点

不同的垃圾回收器所对应的算法不一样效率更不一样。

如何找到专业的网站设计师,以便在镇江地区接单?

在JDK8中默认为ParallelScavenge

new/old两者算法一致只不过ParallelScavenge

对于大大大大大大部分Java业务场景来说都是强引用基本上不会使用到软、弱、虚引用。

而在JDK1.2推出的软、弱、虚引用大部分出现场景都是在缓存中在JDK类库ThreadLocal、WeakHashMap。

框架Mybatis、Netty、以及各种缓存框架等等。

至于为什么要用在缓存中呢也很好理解因为这些引用实际上可有可无完美契合于缓存在有的时候给系统加速在系统内存紧张的时候清除缓存给核心业务使用。

源码剖析

这篇文章的篇幅会比较长也不容易理解。

因为对于软、弱、虚引用处理细节体现在Java层面和JVM层面恰好JVM层面又与GC垃圾回收细节强关联所以笔者只能竭尽所能

Java层面

在Java层面就不得不补充一些前置知识以及Java层面如何处理这些引用。

上图是软、弱、虚引用最基本的表示这里需要区分2个不同的对象一个是软、弱、虚对象一个是软、弱、虚引用的对象。

软、弱、虚对象

所以下文需要介绍软、弱、虚对象的回收机制和区分具体的使用场景相信大家八股文多多少少背过这里跟八股文会有一点点出入

软当系统资源紧张但是又没那么那么紧张的时候根据最近最少使用回收软引用LRU算法当系统资源非常非常紧张的时候直接全部回收。

可以携带引用对象也可以使用ReferenceQueue去处理伴随对象

弱只要发生GC就会回收。

可以携带引用对象也可以使用ReferenceQueue去处理伴随对象

虚只要发生GC就会回收。

不能携带引用对象。

只能使用ReferenceQueue去处理伴随对象

上文有介绍软、弱、虚对象的回收机制这里有提到ReferenceQueue队列所以下文开始介绍Java层面如何使用ReferenceQueue做回收。

static

Handler);handler.setPriority(Thread.MAX_PRIORITY);

handler.start();

在java.lang.ref.Reference类中静态方法中创建了一个ReferenceHandler线程。

所以接下来看线程的执行体。

public

如果pedding不为null那么就代表GC回收到了软、弱、虚引用r

pending;pending

当还没产生pending链表的时候也即没有触发GC回收软、弱、虚引用//

当前线程直接去阻塞等待被JVM唤醒。

lock.wait();}return

把GC回收到了软、弱、虚引用放入到对应的ReferenceQueue中。

//

等待业务自己去处理ReferenceQueue队列。

ReferenceQueue?

super

r;queueLength;lock.notifyAll();return

true;}

是否为空如果为空代表当前GC没有触发回收软、弱、虚引用如果不为空代表当前GC回收软、弱、虚引用并且放入到pedding中把pedding的值放入到ReferenceQueue队列中业务维护的ReferenceQueue队列从队列中poll值去做对应的处理。

所以ReferenceQueue队列是业务层面自己维护传入到Reference中GC回收软、弱、虚引用后会把当前Reference放入到ReferenceQueue队列中。

业务层面再通过poll取到Reference做对应的处理可以是处理伴随对象

下面是WeakHashMap对ReferenceQueue的使用。

至此Java层面的处理已经看完接下来我们需要明白JVM是如何GC处理软、弱、虚引用并且放入到pedding中这样就全部闭环

JVM层面

/hotspot/src/share/vm/memory/genCollectedHeap.cpp

文件中

/hotspot/src/share/vm/memory/genCollectedHeap.cpp

void

GenCollectedHeap::do_collection(bool

full,bool

||collector_policy()-should_clear_all_soft_refs();{…………for

(int

从这里可以看出不同带都有一个引用的处理器。

ReferenceProcessor*

_gens[i]-ref_processor();rp-enable_discovery(true

/*verify_disabled*/,

改变回收策略rp-setup_policy(do_clear_all_soft_refs);

不同代进行垃圾回收。

_gens[i]-collect(full,

size,

gc回收后把回收的软、弱、虚引用赋值给pedding交给Java层面处理//

{rp-enqueue_discovered_references();}

else

rp-set_enqueuing_is_done(false);}}}}…………}

这里根据策略决定是否要清理所有的软引用一般是内存资源极度不够的时候才会新生代或者老年代的垃圾回收器进行垃圾回收这也对应了YGC和FullGC在GC回收后把回收到的软、弱、虚引用赋值给pedding交给Java层面处理

所以接下来需要看到老年代的垃圾回收器进行垃圾回收的时候如何处理的软、弱、虚引用。

/hotspot/src/share/vm/memory/defNewGeneration.cpp

文件中

用于扫描软、弱、虚引用是否存活。

ScanWeakRefClosure

对象扫描器用于GC

klass_scan_closure(fsc_with_no_gc_barrier,gch-rem_set()-klass_rem_set());//

Root直到找完所有的存活对象。

FastEvacuateFollowersClosure

_level,

this,fsc_with_no_gc_barrier,fsc_with_gc_barrier);//

寻找根GC

Root复制到to区或者是老年代。

gch-gen_process_strong_roots(_level,true,

Process

scavengingSharedHeap::ScanningOption(so),fsc_with_no_gc_barrier,true,

walk

nmethodsfsc_with_gc_barrier,klass_scan_closure);//

根据GC

因为这里是处理引用所以这里会处理软、弱、虚等等引用。

evacuate_followers.do_void();//

用于处理引用对象的存活。

FastKeepAliveClosure

keep_alive(this,

scan_weak_ref);ReferenceProcessor*

ref_processor();//

根据clear_all_soft_refs这个bool字段决定是否清理全部的软引用。

rp-setup_policy(clear_all_soft_refs);//

stats

rp-process_discovered_references(is_alive,

keep_alive,

GC还是YGC都会对软、弱、虚引用做处理所以挑选YGC来做分析因为YGC简单一些但是对于软、弱、虚引用做处理都是一样的

由于处理软、弱、虚引用一定会和GC回收细节强关联所以很多是GC回收的细节代码笔者有吧注释给上并且当作黑盒就好。

创建好各种GC回收所需要扫描器这些扫描器最终都有一个共同的任务就是把存活对象复制到to区或者老年代GC

Root做广度遍历找出GC

Root继续找引用直到遍历完整个堆软、弱、虚引的处理这也是接下来的重点

注意这里的软、弱、虚对象和软、弱、虚对象所引用对象是有区别的复制算法只会把软、弱、虚对象做复制软、弱、虚对象引用的对象要后续再做处理。

在看ReferenceProcessor类process_discovered_references方法之前需要介绍一下ReferenceProcessor类。

/hotspot/src/share/vm/memory/referenceProcessor.hpp

文件中

_default_soft_ref_policy;static

ReferencePolicy*

_always_clear_soft_ref_policy;ReferencePolicy*

_num_q;

可以很清楚的看到这里有策略对象和几个DiscoveredList链表。

链表中是保存了被处理的软、弱、虚的Java对象。

并且在遍历完所有的GC

所以接下来看到process_discovered_references方法具体处理细节。

/hotspot/src/share/vm/memory/referenceProcessor.cpp

文件中

ReferenceProcessor::process_discovered_references(BoolObjectClosure*

is_alive,OopClosure*

complete_gc,AbstractRefProcTaskExecutor*

gc_timer)

java_lang_ref_SoftReference::clock();//

soft_count

process_discovered_reflist(_discoveredSoftRefs,

true,is_alive,

时间戳用于LRU算法寻找最近最少使用的软引用。

update_soft_ref_master_clock();//

weak_count

process_discovered_reflist(_discoveredWeakRefs,

NULL,

process_discovered_reflist(_discoveredFinalRefs,

NULL,

process_discovered_reflist(_discoveredPhantomRefs,

NULL,

ReferenceProcessorStats(soft_count,

weak_count,

可以看到不管是软、弱、虚引用的处理都是调用process_discovered_reflist方法。

/hotspot/src/share/vm/memory/referenceProcessor.cpp

文件中

ReferenceProcessor::process_discovered_reflist(DiscoveredList

policy,bool

clear_referent,BoolObjectClosure*

is_alive,OopClosure*

complete_gc,AbstractRefProcTaskExecutor*

task_executor)

这个过滤是判断软、弱、虚对象引用的对象是否还活着如果活着那就不能处理这个引用。

for

(uint

根据clear_referent变量决定最终是否处理引用。

for

(uint

软引用才有策略根据策略决定是否回收对象如果策略不让回收的对象那么就需要从DiscoveredList链表中remove并且保持存活直到下次GC

再尝试回收经过策略的决策后活下来的对象继续做过滤这次过滤是判断软、弱、虚对象引用的对象是否还活着如果活着那就不能处理这个引用所以用不好随时可能内存泄漏如果引用对象是存活的那么就需要从DiscoveredList链表中remove并且保持存活直到下次GC

再尝试回收经过第二步的过滤活下来的对象还要根据clear_referent变量决定最终是否处理引用对象。

这一步只有虚引用才不能处理引用因为虚对象不能引用对象如果clear_reference为false那么就需要从DiscoveredList链表中remove并且保持存活直到下次GC

再尝试回收但是虚引用为false也没关系因为他指向本来就是null。

这里就比较简单了要不永远回收、要不永远不回收要不根据LRU算法得到最近最少使用的软引用优先回收没用的

所以在本文最上面写到软引用在内存紧张的时候但是不是非常紧张的时候会回收最少使用的根据LRU算法在内存非常非常紧张的时候策略直接是AlwaysCLearPolicy策略了就回收所有软引用

当经过层层过滤后最终存活的软、弱、虚对象就存在不同DiscoveredList链表中。

我们在Java层面是从pedding获取到对象所以这边还需要把不同的DiscoveredList链表设置到pedding中。

所以接下来回到GenCollectedHeap::do_collection方法看到enqueue_discovered_references方法

/hotspot/src/share/vm/memory/referenceProcessor.cpp

文件中

ReferenceProcessor::enqueue_discovered_references(AbstractRefProcTaskExecutor*

task_executor)

enqueue_discovered_ref_helperoop(this,

task_executor);

enqueue_discovered_ref_helper(ReferenceProcessor*

ref,AbstractRefProcTaskExecutor*

task_executor)

拿到Reference类中的pedding变量的地址因为pending是一个静态变量所以从mirror拿。

T*

pending_list_addr

(T*)java_lang_ref_Reference::pending_list_addr();//

把链表链到pedding上ref-enqueue_discovered_reflists((HeapWord*)pending_list_addr,

*pending_list_addr;

ReferenceProcessor::enqueue_discovered_reflists(HeapWord*

pending_list_addr,AbstractRefProcTaskExecutor*

task_executor)

只需要把每个链表的头部链到pending就行了。

enqueue_discovered_reflist(_discovered_refs[i],

pending_list_addr);_discovered_refs[i].set_head(NULL);_discovered_refs[i].set_length(0);}

这里就是把经过层层筛选的软、弱、虚链表中的对象链到Reference类中pedding字段上。

最终交给Java层面的ReferenceHandler线程去处理。

使用危险点

上面我们把所有的处理细节都分析完了所以接下来回忆到一处细节点。

/hotspot/src/share/vm/memory/referenceProcessor.cpp

文件中process_discovered_reflist方法这个方法是做过滤处理在process_phase2这个方法做过滤的时候会判断软、弱、虚对象的引用对象是否存活如果存活的情况下是不能做回收的。

所以这里很容易发生内存泄露看到如下的Java代码。

public

Object();weakHashMap.put(o1,new

User(lihayyds));

只要o1不释放这就是内存泄露。

weakHashMap.put(1,new

User(lihayyds));

1是JVM字符串常量池指向的所以这也是一个内存泄露byte[]

bytes1

处理后的大小因为在size里面会去处理System.out.println(Reference

Queue

结果如上图所示发生GC后弱引用根本没有回收就是因为弱引用指向的对象被其他地方强引用导致于在做筛选的过程中被筛选出去了不能去回收它。

那么如果外部的这个强引用不释放那么这个弱引用引用的对象和弱引用对象永远无法回收从而无法达到弱引用的优势变相地说这就是内存泄漏

public

这里直接不让外部引用这个Object对象weakHashMap.put(new

Object(),new

处理后的大小因为在size里面会去处理System.out.println(Reference

Queue

如上图所示弱引用引用的对象不让外部有强引用后直接正常了发生GC就回收了

因为流程特别大强关联GC回收部分所以笔者只能竭尽所能源码注释总结画图来尽量描述明白



SEO优化服务概述

作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。

百度官方合作伙伴 白帽SEO技术 数据驱动优化 效果长期稳定

SEO优化核心服务

网站技术SEO

  • 网站结构优化 - 提升网站爬虫可访问性
  • 页面速度优化 - 缩短加载时间,提高用户体验
  • 移动端适配 - 确保移动设备友好性
  • HTTPS安全协议 - 提升网站安全性与信任度
  • 结构化数据标记 - 增强搜索结果显示效果

内容优化服务

  • 关键词研究与布局 - 精准定位目标关键词
  • 高质量内容创作 - 原创、专业、有价值的内容
  • Meta标签优化 - 提升点击率和相关性
  • 内容更新策略 - 保持网站内容新鲜度
  • 多媒体内容优化 - 图片、视频SEO优化

外链建设策略

  • 高质量外链获取 - 权威网站链接建设
  • 品牌提及监控 - 追踪品牌在线曝光
  • 行业目录提交 - 提升网站基础权威
  • 社交媒体整合 - 增强内容传播力
  • 链接质量分析 - 避免低质量链接风险

SEO服务方案对比

服务项目 基础套餐 标准套餐 高级定制
关键词优化数量 10-20个核心词 30-50个核心词+长尾词 80-150个全方位覆盖
内容优化 基础页面优化 全站内容优化+每月5篇原创 个性化内容策略+每月15篇原创
技术SEO 基本技术检查 全面技术优化+移动适配 深度技术重构+性能优化
外链建设 每月5-10条 每月20-30条高质量外链 每月50+条多渠道外链
数据报告 月度基础报告 双周详细报告+分析 每周深度报告+策略调整
效果保障 3-6个月见效 2-4个月见效 1-3个月快速见效

SEO优化实施流程

我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:

1

网站诊断分析

全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。

2

关键词策略制定

基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。

3

技术优化实施

解决网站技术问题,优化网站结构,提升页面速度和移动端体验。

4

内容优化建设

创作高质量原创内容,优化现有页面,建立内容更新机制。

5

外链建设推广

获取高质量外部链接,建立品牌在线影响力,提升网站权威度。

6

数据监控调整

持续监控排名、流量和转化数据,根据效果调整优化策略。

SEO优化常见问题

SEO优化一般需要多长时间才能看到效果?
SEO是一个渐进的过程,通常需要3-6个月才能看到明显效果。具体时间取决于网站现状、竞争程度和优化强度。我们的标准套餐一般在2-4个月内开始显现效果,高级定制方案可能在1-3个月内就能看到初步成果。
你们使用白帽SEO技术还是黑帽技术?
我们始终坚持使用白帽SEO技术,遵循搜索引擎的官方指南。我们的优化策略注重长期效果和可持续性,绝不使用任何可能导致网站被惩罚的违规手段。作为百度官方合作伙伴,我们承诺提供安全、合规的SEO服务。
SEO优化后效果能持续多久?
通过我们的白帽SEO策略获得的排名和流量具有长期稳定性。一旦网站达到理想排名,只需适当的维护和更新,效果可以持续数年。我们提供优化后维护服务,确保您的网站长期保持竞争优势。
你们提供SEO优化效果保障吗?
我们提供基于数据的SEO效果承诺。根据服务套餐不同,我们承诺在约定时间内将核心关键词优化到指定排名位置,或实现约定的自然流量增长目标。所有承诺都会在服务合同中明确约定,并提供详细的KPI衡量标准。

SEO优化效果数据

基于我们服务的客户数据统计,平均优化效果如下:

+85%
自然搜索流量提升
+120%
关键词排名数量
+60%
网站转化率提升
3-6月
平均见效周期

行业案例 - 制造业

  • 优化前:日均自然流量120,核心词无排名
  • 优化6个月后:日均自然流量950,15个核心词首页排名
  • 效果提升:流量增长692%,询盘量增加320%

行业案例 - 电商

  • 优化前:月均自然订单50单,转化率1.2%
  • 优化4个月后:月均自然订单210单,转化率2.8%
  • 效果提升:订单增长320%,转化率提升133%

行业案例 - 教育

  • 优化前:月均咨询量35个,主要依赖付费广告
  • 优化5个月后:月均咨询量180个,自然流量占比65%
  • 效果提升:咨询量增长414%,营销成本降低57%

为什么选择我们的SEO服务

专业团队

  • 10年以上SEO经验专家带队
  • 百度、Google认证工程师
  • 内容创作、技术开发、数据分析多领域团队
  • 持续培训保持技术领先

数据驱动

  • 自主研发SEO分析工具
  • 实时排名监控系统
  • 竞争对手深度分析
  • 效果可视化报告

透明合作

  • 清晰的服务内容和价格
  • 定期进展汇报和沟通
  • 效果数据实时可查
  • 灵活的合同条款

我们的SEO服务理念

我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。

提交需求或反馈

Demand feedback