线程、内存泄露问题 顺便过年散分

zhuminghua 2009-01-23 09:54:40
同事写的一个简单的测试程序,用定时器往TList里加对象,另外开一个线程进行扫描TList,发现里面有对象就释放掉对象。但是时间长了会内存泄露,在任务管理器里可以看到进程不断增加。看了半天没找出问题,代码如下:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls;


type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Timer1: TTimer;
Button3: TButton;
procedure Timer1Timer(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation
uses
Unit2;

var
mythread:repthread;


{$R *.dfm}

procedure TForm1.Timer1Timer(Sender: TObject);
var
newtestclass:testclass;
begin
mythread.cs.Enter;
newtestclass:=testclass.Create;
newtestclass.val:=100;
// newtestclass.buflen:=100;
// setlength(newtestclass.buf,newtestclass.buflen);
mythread.replist.Add(newtestclass);
mythread.cs.Leave;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Timer1.Enabled:=true;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
Timer1.Enabled:=false;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
mythread:=repthread.Create(false);
end;

end.



unit Unit2;

interface

uses
Classes,SyncObjs,SysUtils;

type
testclass=class
val:integer;
// buf:array of byte;
// buflen:integer;
// public
// destructor Destroy; override;
end;
type
repthread = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
public
replist:TLIST;
RUNing:boolean;
cs:TCriticalSection;
end;

implementation

uses Unit1;

{ repthread }

procedure repthread.Execute;
var
ACTtestclass:testclass;
Index: Integer;
begin
{ Place thread code here }
replist:=TLIST.Create;
RUNing:=true;
cs:=TCriticalSection.Create;
while RUNing do
begin
cs.Enter;
if replist.Count>0 then
begin
{ ACTtestclass:=testclass(replist.Items[0]);
replist.Delete(0);
// setlength(ACTtestclass.buf,0);
ACTtestclass.Destroy;
replist.Pack; }
Index := RepList.Count - 1;
if RepList.Items[Index] <> nil then
begin
TObject(RepList.Items[Index]).Free;
RepList.Delete(Index);
end;
end
else
begin
sleep(100);
end;
cs.Leave;
end;
cs.Free;
end;


{destructor testclass.Destroy;
begin
inherited;
end;}
end.
...全文
291 33 打赏 收藏 转发到动态 举报
写回复
用AI写文章
33 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhuminghua 2009-02-02
  • 打赏
  • 举报
回复
太久没用,都忘记有ThreadList这东西了
liangpei2008 2009-02-01
  • 打赏
  • 举报
回复

//应该是线程同步的问题,用ThreadList做多好,LZ非要自己实现一遍ThreadList的功能......

lenism521 2009-01-24
  • 打赏
  • 举报
回复
我也遇到过这个问题!~ 某个对象没有释放或者释放不是时候。。 你那个临界区没必要在线程执行过程里创建再释放掉!~应该在线程初始化里创建。注意你的timer里还用到临界区呢!~ 解决办法:你把线程里的cs.Free去掉!~临界区初始化在线程初始化里创建!
zhuminghua 2009-01-24
  • 打赏
  • 举报
回复
自己丁页
fjtxwd 2009-01-24
  • 打赏
  • 举报
回复
舞台中央的我 2009-01-23
  • 打赏
  • 举报
回复
好长阿 ! 县学习 !
starluck 2009-01-23
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 Avan_Lau 的回复:]
哈哈,我明天才回家过年。
楼主,把timer时间间隔,设长一点,再看内存状况
[/Quote]


要不就把時間調長點,看內存的情況吧。
金卯刀 2009-01-23
  • 打赏
  • 举报
回复
哈哈,我明天才回家过年。
楼主,把timer时间间隔,设长一点,再看内存状况
simonhehe 2009-01-23
  • 打赏
  • 举报
回复
oo
楼上几位这是不过年了啊
zhuminghua 2009-01-23
  • 打赏
  • 举报
回复
汗,要怎么注意啊,10几行代码摆就在那,肯定是没用申请其它内存啊
金卯刀 2009-01-23
  • 打赏
  • 举报
回复
综合timer时间间隔、线程优先级和临界区等其他因素考虑,子线程得到释放主 线程对象的机会有多少呢?当然还要考虑楼上的说法
starluck 2009-01-23
  • 打赏
  • 举报
回复



要注意的你 testclass 有沒有申請其它的內存,在FREE的時候是不是沒有釋放。

還有內存增加過快,釋放需要一定的時間。
zhuminghua 2009-01-23
  • 打赏
  • 举报
回复
10几分钟涨了40几K,如果长时间跑,程序肯定会死掉的
bdmh 2009-01-23
  • 打赏
  • 举报
回复
你的泄露程度有多少,如果只是很小的连续增长,也算正常,因为在程序高速运行时,数据的计算必定要占用内存,而释放是需要时间的,内存没有立即的减小,是可以理解的

所以你要看你程序的泄露程度,如果内存没有疯狂的增长,而且可以回落,应该算正常
zhuminghua 2009-01-23
  • 打赏
  • 举报
回复
就算将TCriticalSection和TList对象放到Create里面,还是会有内存泄露的,你们可以试试看的
starluck 2009-01-23
  • 打赏
  • 举报
回复
問題太大了,再改進下;




unit Unit2;

interface

uses
Classes,SyncObjs,SysUtils;

type
testclass=class
val:integer;
// buf:array of byte;
// buflen:integer;
// public
// destructor Destroy; override;
end;
type
repthread = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
public
replist:TLIST;
RUNing:boolean;
cs:TCriticalSection;
constructor Create(CreateSuspended: Boolean); overload;
destructor Destroy; override;
end;

implementation

uses Unit1;

{ repthread }
procedure repthread.Create(CreateSuspended: Boolean);
begin
inherited create;
{ Place thread code here }
replist:=TLIST.Create;
RUNing:=true;
cs:=TCriticalSection.Create; // 建立臨界限 ,如果放在EXECUTE裏那不亂了。
end;

destructor repthread.Destroy;
begin
Runing := false;
if Assigned(repList) then FreeAndNil(repList);
cs.free;
inherited Destroy;
end;

procedure repthread.Execute;
var
ACTtestclass:testclass;
Index: Integer;
begin

while RUNing do
begin
cs.Enter;
if replist.Count>0 then
begin
Index := RepList.Count - 1;
if RepList.Items[Index] <> nil then
begin
TObject(RepList.Items[Index]).Free;
RepList.Delete(Index);
end;
end
else
begin
sleep(100);
end;
cs.Leave;
end;
end;


{destructor testclass.Destroy;
begin
inherited;
end;}
end.



金卯刀 2009-01-23
  • 打赏
  • 举报
回复
10樓的答案應該可以,修正一下十一樓的,手誤:
應該是屬于線程的范疇
bdmh 2009-01-23
  • 打赏
  • 举报
回复
临界设置是有点问题
放到Execute外创建
金卯刀 2009-01-23
  • 打赏
  • 举报
回复
procedure TForm1.Timer1Timer(Sender: TObject);//后面執行這個事件
var
newtestclass:testclass;
begin
mythread.cs.Enter; //在主線程執行時,調用子線程的東西,這時系統會是什么狀況?
newtestclass:=testclass.Create;
newtestclass.val:=100;
// newtestclass.buflen:=100;
// setlength(newtestclass.buf,newtestclass.buflen);
mythread.replist.Add(newtestclass);
mythread.cs.Leave;
end;
procedure TForm1.Button3Click(Sender: TObject);//你應該是先執行這個事件
begin
mythread:=repthread.Create(false);
end;

線程代碼中的臨界區以及list的創建是在execute中的,應該是屬于線程的范疇。
你可以把這兩個對象放到子線程的create構造方法里面,或者放到主線程創建,這樣應該就不會有問題了。
starluck 2009-01-23
  • 打赏
  • 举报
回复


unit Unit2;

interface

uses
Classes,SyncObjs,SysUtils;

type
testclass=class
val:integer;
// buf:array of byte;
// buflen:integer;
// public
// destructor Destroy; override;
end;
type
repthread = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
public
replist:TLIST;
RUNing:boolean;
cs:TCriticalSection;
constructor Create(CreateSuspended: Boolean); overload;
end;

implementation

uses Unit1;

{ repthread }
procedure repthread.Create(CreateSuspended: Boolean);
begin
inherited create;
{ Place thread code here }
replist:=TLIST.Create;
RUNing:=true;
cs:=TCriticalSection.Create; // 建立臨界限 ,如果放在EXECUTE裏那不亂了。
end;

procedure repthread.Execute;
var
ACTtestclass:testclass;
Index: Integer;
begin

while RUNing do
begin
cs.Enter;
if replist.Count>0 then
begin
{ ACTtestclass:=testclass(replist.Items[0]);
replist.Delete(0);
// setlength(ACTtestclass.buf,0);
ACTtestclass.Destroy;
replist.Pack; }
Index := RepList.Count - 1;
if RepList.Items[Index] <> nil then
begin
TObject(RepList.Items[Index]).Free;
RepList.Delete(Index);
end;
end
else
begin
sleep(100);
end;
cs.Leave;
end;
cs.Free;
end;


{destructor testclass.Destroy;
begin
inherited;
end;}
end.


加载更多回复(13)
注: 软件不断更新中,有什么意见大家多多提,偶看可以的就采纳.....gh0st的成长,离不开大家的帮助. 2008/1/27 11:16 : 优化了屏幕传输算法,CPU利用率更低 2008/1/27 16:06 : 驱动以资源方式写入安装文件跟DLL文件中,优化屏幕传输 2008/1/27 17:26 : 修正驱动安装时的一个Bug 2008/1/28 05:28 : 服务端安装强化,加入服务检测,守护线程强化,加入禁用监视,顺便做了下免杀 2008/1/29 12:47 : 改变服务端安装启动方式,隐藏服务,去掉驱动程序和守护线程,感谢Lzx无私的帮助... 2008/1/29 16:12 : 修正键盘记录重复问题,优化服务端上线方式 2008/1/30 04:11 : 修正服务端网络内核的一个导致异常的Bug,优化服务端大小到100K 2008/1/31 01:28 : 重写服务端网络内核,加入数据包验证,及重发功能,更加稳定 2008/1/31 11:36 : 修正服务端网络内核一个导致数据包混乱的问题,加入帧速限制,传输不稳定的情况从此消失... 2008/2/01 10:54 : 主动防御功能加强,过卡巴全监控,瑞星,Kis6,Kis7,Norton,ZoneAlarm,江民2008等杀毒软件.下个版本准备过所有杀软的主动...期待吧. 2008/2/01 14:18 : 加入服务端异常处理,更新稳定,请各位帮助测试.. 2008/2/01 15:39 : 修正服务端删除后不能安装的致命错误 2008/2/01 23:35 : 改写了下服务端一些函数,增加稳定性,春季过后重写服务端吧,简洁下程序. 2008/2/02 19:51 : 修正服务端视频监控功能的一些BUG 2008/2/03 00:40 : 屏幕监控加入显示远程鼠标功能 2008/2/05 16:46 : 重写屏幕传输算法,屏幕传输更快,控制更稳定.. 2008/2/05 23:45 : 还是网络内核跟屏幕传输方面,只求更快,不求最快,前版本屏幕传输有问题,旧版本不能上线,请用最新版本... 2008/2/06 17:32 : 服务端做了些优化,加入跟踪远程光标的功能,旧版本不能上线,请用最新版本 2008/2/07 00:57 : 改了些服务端,没事优化优化,准备过完年,大整一下,新年快乐... 2008/2/07 16:02 : 没事加了个托盘功能,做了些代码优化,一个人过年,有点郁闷... 2008/2/07 20:42 : 修正服务端一个句柄泄漏的问题.. 2008/2/08 22:08 : 全面优化了下服务端,新加了备注功能. 2008/2/09 22:58 : 修正一些大家提到的问题,Gh0st RAT Beta 2.1 发布 2008/2/11 00:18 : 修正服务端安装的一个BUG,静心研究ACE中,暂停更新................... 2008/2/17 16:14 : 保存配置文件,服务端支持socks5代理上线,加入下载更新功能,屏幕控制加入,黑屏,锁定等功能 2008/2/20 10:49 : 应大家要求,看了看江民2008的垃圾主动,连注册表都没,随便改了下服务端,过江民2008主动.其它有啥主动过不了的,抓图,我抽空解决 Gh0st问答: 2008/2/20 09:26 : 改了下服务端一些网络方面的东西,看对2003掉线情况是否有效,望大家测试,多谢了. 2008/2/21 15:43 : 服务端掉线问题,重启后不上线问题,测试版本,请大家测试 2008/2/22 19:47 : 解决重启后服务端不上线问题,加强对抗主动防御的功能 2008/2/23 17:11 : 全面优化了下服务端,加强稳定性,请大家测试 2008/2/23 19:03 : 修正视频监视的一个小BUG 2008/2/24 01:55 : 文件管理中加入本地和远程运行功能,优他了部分代码,旧版本不会上线,请用新版本 2008/2/24 12:56 : 修正文件管理中一个低级错误,下载更新的一个错误 2008/2/26 00:00 : 完美解决重复安装,重复上线问题,发布gh0st2.5,准备第二阶段的开发,重点在稳定,实用上.... 声明下软件的安装方式: 如果安装时发现有相同配置的服务端已经安装过,就不安装也不删除,跟鸽子一个原理,我是靠字串区别的 2008/3/2 06:35 : 本着我写gh0st的初衷,一个共享,免费,的软件,到今天为止,算是对大家一个交代,新版本开发中,此版本开源..装上VC6,打造属于你们自己的gh0st吧.. 本人不保留版权,任何信息,自由修改,多谢一直以来大家的支持,我会继续努力的 在此声明:此软件无作者,无版权,由此软件造成的任何不良后果与红狼无关,多谢!!!! 1:为什么服务端下线后,控制端没反应 答:控制端检测心跳包间隔为1分钟,过一分钟后,自然就下线了 2:下线后多长时间才能再上线 答:服务端断线重连间隔为1分钟 3:怎么找不到在哪控制屏幕,跟键盘的离线记录 答:在标题栏点右键,也就是系统菜单,就能看到 4:为什么有时会出现重复上线的问题 答:服务端发生异常,就会重新连接创建第二个连接,但是第一个连接已经断开了,控制端在其心跳超时的情况下,会删除 心跳超时为1分钟,也就是说,重复上线情况会持续一分钟,自然就没有了 5:有些大家提到的有些功能,为什么没有加上去 答:gh0st作者有自己的想法,自己的宗旨 6:提出建议或问题后多长时间能解决 答:偶以最快的速度,把gh0st做的专业,强大,稳定. 7: 如果做免杀??? 答:服务端用ResourceHacker或者别的资源提取工具打开,会看到两个资源,分别是DLL文件和恢复SSDT的驱动,开始动手吧.... 8:能不能加入系统服务管理的功能呢? 答:系统服务管理,注册表管理等这些,我感觉没必要加才不加的,服务管理sc就能搞定,注册表reg就搞定,服务端加这些函数,对免杀也有影响 9:希望能够加入服务端安装判断的功能,要不然连续运行两次,就上线两次。 答:现在服务端安装是共享模式,可以安装多个,上线多个,实际上不是重复上线,版本稳定后,服务端三种安装模式:独占模式,单一模式,共享模式,顾名思义的理解吧 10: ...虚位以待...
控制端采用IOCP模型,数据传输采用zlib压缩方式稳定快速,上线数量无上限,可同时控制上万台主机控制端自动检测CPU使用率调整自己的工作线程, 稳定高效宿主为svchost以系统服务启动,有远程守护线程,上线间隔为两分钟。心跳包机制防止意外掉线..支持HTTP和DNS上线两种方式自动恢复SSDT(这功能干什么,大家都知道,免杀自己做吧),安装本程序需要管理员权限控制端279K,返朴归真的界面,生成的服务端无壳,106 K,EXE内的资源用UPX压缩, 可安装多个服务端其它细节方面的功能大家自己去发现吧功能:文件管理 完全仿Radmin所写, 文件、文件夹批量上传、删除、下载、创建、重命名屏幕监视 扫描算法速度最快可达到120帧/秒,差异算法适合网络极差的情况下传输,传输速度快,控制屏幕,发送Ctrl+Alt+Del,剪贴板操作,7种色彩显示方式,等......键盘记录 可记录中英文信息,离线记录(记录上限50M)功能远程终端 一个简单shell系统管理 进程管理,窗口管理,拨号上网密码获取视频查看 查看远程摄像头,快照,录像,压缩等功能...语音监听 监听远程语音,同时也可以把本地语音传送给远程,进行语音聊天,GSM610压缩方式,传输流畅会话管理 注销,重启,关机,卸载服务端其它功能 下载执行指定URL中的程序,隐藏或者显示访问指定网址,清除系统日志地址位置 将IP数据库文件QQWry.Dat放置程序同目录下即可显示地理位置集群控制 可同时控制多台主机,同时打开视频监控等管理功能备注功能 .........注: 软件不断更新中,有什么意见大家多多提,偶看可以的就采纳.....gh0st的成长,离不开大家的帮助.2008/1/27 11:16 : 优化了屏幕传输算法,CPU利用率更低2008/1/27 16:06 : 驱动以资源方式写入安装文件跟DLL文件中,优化屏幕传输2008/1/27 17:26 : 修正驱动安装时的一个Bug2008/1/28 05:28 : 服务端安装强化,加入服务检测,守护线程强化,加入禁用监视,顺便做了下免杀2008/1/29 12:47 : 改变服务端安装启动方式,隐藏服务,去掉驱动程序和守护线程,感谢Lzx无私的帮助...2008/1/29 16:12 : 修正键盘记录重复问题,优化服务端上线方式2008/1/30 04:11 : 修正服务端网络内核的一个导致异常的Bug,优化服务端大小到100K2008/1/31 01:28 : 重写服务端网络内核,加入数据包验证,及重发功能,更加稳定2008/1/31 11:36 : 修正服务端网络内核一个导致数据包混乱的问题,加入帧速限制,传输不稳定的情况从此消失...2008/2/01 10:54 : 主动防御功能加强,过卡巴全监控,瑞星,Kis6,Kis7,Norton,ZoneAlarm,江民2008等杀毒软件.下个版本准备过所有杀软的主动...期待吧.2008/2/01 14:18 : 加入服务端异常处理,更新稳定,请各位帮助测试..2008/2/01 15:39 : 修正服务端删除后不能安装的致命错误2008/2/01 23:35 : 改写了下服务端一些函数,增加稳定性,春季过后重写服务端吧,简洁下程序.2008/2/02 19:51 : 修正服务端视频监控功能的一些BUG2008/2/03 00:40 : 屏幕监控加入显示远程鼠标功能2008/2/05 16:46 : 重写屏幕传输算法,屏幕传输更快,控制更稳定..2008/2/05 23:45 : 还是网络内核跟屏幕传输方面,只求更快,不求最快,前版本屏幕传输有问题,旧版本不能上线,请用最新版本...2008/2/06 17:32 : 服务端做了些优化,加入跟踪远程光标的功能,旧版本不能上线,请用最新版本2008/2/07 00:57 : 改了些服务端,没事优化优化,准备过完年,大整一下,新年快乐...2008/2/07 16:02 : 没事加了个托盘功能,做了些代码优化,一个人过年,有点郁闷...2008/2/07 20:42 : 修正服务端一个句柄泄漏的问题..2008/2/08 22:08 : 全面优化了下服务端,新加了备注功能.2008/2/09 22:58 : 修正一些大家提到的问题,Gh0st RAT Beta 2.1 发布2008/2/11 00:18 : 修正服务端安装的一个BUG,静心研究ACE中,暂停更新...................2008/2/17 16:14 : 保存配置文件,服务端支持socks5代理上线,加入下载更新功能,屏幕控制加入,黑屏,锁定等功能2008/2/20 10:49 : 应大家要求,看了看江民2008的垃圾主动,连注册表都没,随便改了下服务端,过江民2008主动.其它有啥主动过不了的,抓图,我抽空解决2008/2/20 09:26 : 改了下服务端一些网络方面的东西,看对2003掉线情况是否有效,望大家测试,多谢了.2008/2/21 15:43 : 服务端掉线问题,重启后不上线问题,测试版本,请大家测试2008/2/22 19:47 : 解决重启后服务端不上线问题,加强对抗主动防御的功能2008/2/23 17:11 : 全面优化了下服务端,加强稳定性,请大家测试2008/2/23 19:03 : 修正视频监视的一个小BUG2008/2/24 01:55 : 文件管理中加入本地和远程运行功能,优他了部分代码,旧版本不会上线,请用新版本2008/2/24 12:56 : 修正文件管理中一个低级错误,下载更新的一个错误2008/2/26 00:00 : 完美解决重复安装,重复上线问题,发布gh0st2.5,2008/3/20 21:52 : 服务端全部优化一遍,加入语音监听,屏幕监视的算法优化...2.6发布2008/3/24 18:52 : 抽出时间来,视频采用选择性压缩,强大的H263压缩算法,100:1的压缩率,加入快照功能...2.7发布2008/3/25 02:42 : 修正网友提出的问题,如下载网址输入有限制等,一些人性化细节方面的修改...2008/3/26 05:01 : 修正视频的一个解码器处理的BUG,加入智能选择编码器,调整屏幕传输4位调色板....2.712008/3/28 11:01 : 修正视频对一些摄像头不兼容的bug,加入录像功能,修正服务端一个导致整体稳定性的bug,此版本历来最稳定的...不与前版本相兼容2008/4/16 01:28 : 屏幕算法加入热点跟踪,心跳包方式改用保活方式,优化网络内核,实际压缩测试2003服务器,超过4万台同时上线,服务端生成方式为文件尾追加配置信息,壳为upackDLL资源也用upack加了壳,脱壳后,可自由更改,导入,不影响使用,软件标题日期,不做改变,2.8是个好数字,改动了一些其它细节方面的问题2008/4/18 23:44 : 完美解决键盘记录重复记录等问题.2008/5/10 20:47 : 修正2003 R2下下载更新或者下载执行时造成服务器崩溃的BUG,以及更新后黑屏的BUG,发布3.02008/5/11 18:10 : 超时改为3分钟,采用双保活机制度,防止网络异常导致出现死连接, 致使务端无法上线的BUG,请不要再用旧版本,最近更新的都是一些致命问题2008/5/14 00:26 : 修正一些摄像头无法显示的BUG,发布3.2版本2008/5/16 02:48 : 更改服务端安装方式,以前的安装方式很不稳定,现在的更加稳定,在多种操作系统中测试通过,可以自定义服务显示名称,描述....3.42008/5/17 15:03 : 换心跳方式,对付任何情况下产生的死连接,安装删除更加稳定,发布3.52008/5/17 20:32 : 修正3.5恢复SSDT失败的BUG,一个小小的笔误,实在不好意思.请大家不要用旧版本了,些版本是历来最稳定的,旧版本BUG太多,看更新记录就知道了,下个版本出来会有很长时间,大家可以放心的用,更新周期会变长2008/5/22 17:11 : 偶再三思考下,开源,开源是最好的办法,我就开源.....我就不信了...3.6开源视频压缩支持的编码格式,按优先级排列:Microsoft H.263 Video CodecIntel Indeo(R) Video R3.2Microsoft MPEG-4 Video Codec V2Cinepak Codec by Radius声明下软件的安装方式:如果安装时发现有相同配置的服务端已经安装过,就不安装也不删除,跟鸽子一个原理,我是靠字串区别的2008/3/2 06:35 : 本着我们红狼写gh0st的初衷,一个共享,免费,的软件,到今天为止,算是对大家一个交代,新版本开发中,经小组内部讨论将此版本开源..装上VC6,打造属于你们自己的gh0st吧..我们不保留版权,任何信息,自由修改,多谢一直以来大家的支持,我们会继续努力的

16,748

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧