1. C++内存管理核心概念解析
C++作为一门系统级编程语言,其内存管理能力一直是区别于其他高级语言的核心特征。与Java、Python等语言不同,C++要求开发者直接参与内存的分配与释放,这种设计带来了极高的性能优势,同时也带来了复杂的管理责任。
指针是C++内存操作的基石,它本质上是一个存储内存地址的变量。在32位系统中指针占4字节,64位系统中占8字节。理解指针的关键在于区分指针本身(地址值)和指针指向的内容(内存中的数据)。例如:
cpp复制int* p = new int(42); // p是指针变量,存储着堆内存地址
cout << *p; // *p解引用获取该地址存储的整数值42
内存分区模型是理解C++内存布局的基础:
- 代码区:存放函数体的二进制代码,由操作系统管理
- 全局区:存放全局变量、静态变量和常量(字符串常量等)
- 栈区:由编译器自动分配释放,存放函数参数、局部变量等
- 堆区:由程序员手动分配释放,通过new/malloc申请
关键区别:栈空间有限(通常1-2MB),分配速度快;堆空间大但分配慢,需要手动管理。错误使用会导致栈溢出或内存泄漏。
2. 动态内存管理实战
2.1 new/delete操作符深度使用
new操作符在堆上分配内存时实际完成三个步骤:
- 调用operator new分配原始内存
- 在内存上调用构造函数初始化对象
- 返回指向新对象的指针
对应的delete操作符则执行相反过程:
cpp复制class MyClass {
public:
MyClass() { cout << "构造\n"; }
~MyClass() { cout << "析构\n"; }
};
MyClass* obj = new MyClass(); // 输出"构造"
delete obj; // 输出"析构"
数组形式的new[]/delete[]需要特别注意:
cpp复制int* arr = new int[10]; // 分配10个int的连续空间# 1. 概述
本文分享 **Dubbo 的线程池策略**。在 [《精尽 Dubbo 源码分析 —— 线程池》](http://svip.iocoder.cn/Dubbo/thread-policy/?self) 一文中,我们已经看到,Dubbo 提供了**五种**线程池的实现:
- `fixed` 固定大小线程池,启动时建立线程,不关闭,一直持有。( **缺省** )
- `cached` 缓存线程池,空闲一分钟自动删除,需要时重建。
- `limited` 可伸缩线程池,但池中的线程数只会增长不会收缩。只增长不收缩的目的是为了避免收缩时突然来了大流量引起的性能问题。
- `eager` 优先创建`Worker`线程池。在任务数大于`corePoolSize`但是小于`maximumPoolSize`时,优先创建`Worker`来处理任务。当任务数大于`maximumPoolSize`时,将任务放入阻塞队列中。阻塞队列充满时抛出`RejectedExecutionException`。( 相比于 `cached` 的 `threads` 无上限,`eager` 通过`maximumPoolSize`来限制 )
- `direct` 在请求线程中直接执行,不创建新的线程。
本文涉及的类,如下图所示:

# 2. ThreadPool
`com.alibaba.dubbo.common.threadpool.ThreadPool` ,线程池接口。代码如下:
```Java
@SPI("fixed")
public interface ThreadPool {
/**
* 线程池
*
* @param url 线程参数
* @return 线程池
*/
@Adaptive({Constants.THREA[DPO](https://taotoken.net?utm_source=hardware)OL_KEY})
Executor getExecutor(URL url);
}
@SPI("fixed")注解,Dubbo SPI 拓展点,默认为"fixed"。@Adaptive({Constants.THREADPOOL_KEY})注解,基于 Dubbo SPI Adaptive 机制,加载对应的线程池实现,使用URL.threadpool属性。#getExecutor(url)方法,获得对应的线程池的执行器。
3. FixedThreadPool
com.alibaba.dubbo.common.threadpool.support.fixed.FixedThreadPool ,实现 ThreadPool 接口,固定大小线程池,启动时建立线程,不关闭,一直持有。代码如下:
Java复制public class FixedThreadPool implements ThreadPool {
@Override
public Executor getExecutor(URL url) {
// 线程名
String name = url.getParameter(Constants.THREAD_NAME_KEY, Constants.DEFAULT_THREAD_NAME);
// 线程数
int threads = url.getParameter(Constants.THREADS_KEY, Constants.DEFAULT_THREADS);
// 队列数
int queues = url.getParameter(Constants.QUEUES_KEY, Constants.DEFAULT_QUEUES);
// 创建执行器
return new ThreadPoolExecutor(threads, threads, 0, TimeUnit.MILLISECONDS,
queues == 0 ? new SynchronousQueue<Runnable>() :
(queues < 0 ? new LinkedBlockingQueue<Runnable>()
: new LinkedBlockingQueue<Runnable>(queues)),
new NamedThreadFactory(name, true), new AbortPolicyWithReport(name, url));
}
}
-
默认情况下,采用
Executors#newFixedThreadPool(int nThreads)方法,创建执行器。差异点如下:-
队列大小
queues可以配置,并且可以配为-1,表示无限大。 -
线程池的拒绝策略,使用 AbortPolicyWithReport ,实现代码如下:
Java复制public class AbortPolicyWithReport extends ThreadPoolExecutor.AbortPolicy { protected static final Logger logger = LoggerFactory.getLogger(AbortPolicyWithReport.class); private final String threadName; private final URL url; public AbortPolicyWithReport(String threadName, URL url) { this.threadName = threadName; this.url = url; } @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { String msg = String.format("Thread pool is EXHAUSTED!" + " Thread Name: %s, Pool Size: %d (active: %d, core: %d, max: %d, largest: %d), Task: %d (completed: %d)," + " Executor status:(isShutdown:%s, isTerminated:%s, isTermina
-
