Memory erlang内存在c:l文件时增长
我发现了一个问题,但我不确定这是错误还是其他,我不知道如何处理它 一次,两次输入c:l(test_data)文件,发现关系过程的记忆都在增长。 这是我的测试 操作系统:linux还是win Erlang版本:R19或R20 Dir:erl_测试 文件: test_server.erl、test_statem.erl、test_fsm.erl、test_data.erl、test_server2.erl test_data.erl是一个大文件,1M 手术是:Memory erlang内存在c:l文件时增长,memory,erlang,Memory,Erlang,我发现了一个问题,但我不确定这是错误还是其他,我不知道如何处理它 一次,两次输入c:l(test_data)文件,发现关系过程的记忆都在增长。 这是我的测试 操作系统:linux还是win Erlang版本:R19或R20 Dir:erl_测试 文件: test_server.erl、test_statem.erl、test_fsm.erl、test_data.erl、test_server2.erl test_data.erl是一个大文件,1M 手术是: erl -s make all erl
erl -s make all
erl
main:c(1). %% will make 4 process: fsm , statem, server
observer:start(). %% open observer, see process memory
main:l(). %% will reload test_data.erl
%% look 4 processes memory
main:l(). %% reload test_data again
%% look 4 processes memory, become large
main.erl和test_server.erl代码:
%% main.erl
-module(main).
-export([c/1, l/0]).
%% make process
c(N) ->
test_fsm:create_mon(N),
test_statem:create_mon(N),
test_server:create_mon(N),
test_server2:create_mon(N),
ok.
%% reload test_data
l()->
c:l(test_data).
%% test_server.erl, test_fsm, test_statem's code the same as test_server
-module(test_server).
-behaviour(gen_server).
%% API
-export([start_link/0, create_mon/1]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
-define(SERVER, ?MODULE).
-record(state, {mon = undefined}).
create_mon(0) -> ok;
create_mon(N) ->
start_link(),
create_mon(N-1).
start_link() ->
gen_server:start(?MODULE, [], []).
init([]) ->
erlang:send_after(10000, self(), init),
{ok, #state{mon = test_data:get(1)}}.
...
handle_info(_Info, State) ->
Mon = test_data:get(1),
erlang:send_after(10000, self(), info),
{noreply, State#state{mon = Mon}}.
...
%%test_data.erl
-module(test_data).
-export([get/1]).
-include("test.hrl").
get(1) ->
#mon{id = 1,name = "test", kind = 10,boss = 0,type = 0,career = 0,color
= 1,auto = 0,icon = 5010011,icon_scale = 1,icon_effect =
"",icon_texture = 0,weapon_id = 5010011,foot_icon = 0,desc =
"",lv = 1,hp_lim = 1000,att = 0,def = 0,hit = 0,dodge = 0,crit =
0,ten = 0,wreck = 0,resist = 0,special_attr = [],resum =
[],striking_distance = 0,tracing_distance = 0,warning_range =
0,hate_range = 0,speed = 0,skill = [{1110000003,1}],retime =
0,att_time = 0,att_type = 0,drop = 0,exp = 100,out =
0,collect_time = 0,collect_count = 0,is_fight_back =
0,is_be_atted = 1,is_be_clicked = 1,is_armor = 0,del_hp_each_time
= [10,10],figure_visible = 1,is_hide_hp = 0,is_hit_ac =
0,exp_share_type = 0,anger = 0};
...
get(10000) ->
...
....
该图像是观察者的结果:听起来您的进程在测试数据模块的常量池中保存对对象的引用。这几乎不需要内存,因为引用基本上只是指针。当模块的旧版本被清除时,常量池随之消失,因此测试服务器不能再仅仅保存引用;它需要在自己的堆中有一个数据副本 见本讨论: 所有文本都属于加载的模块实例。当那个(旧)模块 实例被清除,所有进程堆被扫描并包含 这些文本将执行一个特殊的垃圾收集,其中 是复制的
请描述一下你所做的尝试。你说“热”是什么意思?谢谢,我知道了。但如果我有1000个这样的进程,当清除模块实例时,内存就像“泄漏”。如果我不触发主要gc,内存就不会改变。为什么进程文本不能自动gc?有什么好办法解决这个问题吗?一般来说,在需要内存时处理GC。如果您的进程不经常分配内存,那么它们也不会经常使用GC。作为一种解决方案,您可以在流程中直接触发GC(在计时器上,或者在收到消息时,等等),或者使用gen_server的休眠功能。