createserver怎么读(creates怎么读音发音)

http://www.itjxue.com  2023-02-22 01:39  来源:未知  点击次数: 

3dmax修改命令中英文对照

File:文件: GlobalOutputGamma整体输出Gamma Basic基本 (edit)(编辑) ActiveHours活动小时 Advanced高级 Alignment对齐 AlphaChannelAlpha通道 alreadyexists.Overwrite?已经存在.覆盖吗? AlternateSourcePath交替源路径 Aspectratio长宽比 AVIFileCompressionSetupAVI文件压缩设置 AVIInfoAVI信息 Binding绑定 Bitmap位图 BlueChannelBlue通道 Clear清除 ColorContrast:颜色对比度: ColorDepth颜色深度 CommandLineOptions命令行参数 Compressor压缩器 Coordinates坐标系 CreateScatter创建分散 CustomSize自定义大小 DefaultMaterialandTextures缺省材质与纹理 DefineMask定义罩框 Deinterlace不交错 Details细节 DeviceSelection设备选择 Direction方向 Editor编辑器 EventControl事件控制 Export输出 ExternalEvent外部事件 FailedServers服务器失败 Fields场 Film/FrameInformation电影/帧信息 Filter过滤器 FlagProperties标记属性 fordeletedbiped用于删除两足 ForegroundImage前景图象 Frames帧 General总体 Gradients渐变 GreenChannelGreen通道 Header头 IFLControlPanelIFL控制面板 Image图象 ImageContrastControl图象对比控制器 ImageControl图象控制 ImageDataFormat图象数据格式 ImageDriver图象驱动 ImageFile图象文件 ImageFilter图象过滤器 ImageGeneration图象产生 ImageInformation图象信息 ImageInformation图象信息 ImageInput图象输入 ImageInputOptions图象输入选项 ImageInputOptions图象输入设置 ImageLayer图象层 ImageLayerPlug-In图象层插件 InputGammaSettings输入Gamma设置 JobName工作名称 JobOutputPath工作输出路径 LastImageTrack最后图象轨迹 Log日记 LogFileMaintenance记录文件维护 Luminance发光 ManagerNameorIPAddress管理名称或IP地址 MapAmount贴图数量 Mask罩框 MaterialEffects材质特效 Miscellaneous杂项 Mode模式 NegativeFilter阴性过滤器 NetworkJobAssignment网络工作分配 Notifications报告 NumberofTimes时间数量 Object物体 Open打开 OptionalChannels(3dsmaxChannels)可选通道(3dsmaxChannels) OptionalPixelData优化象素数据 Options选项 Output输出 OutputFile输出文件 OutputGammaSettings输出Gamma设置 OutputSettings:输出设置: OutputSize输出大小 "Pixel(1224,1024)""象素(1224,1024)" PlugIn插件 PreviewSetup预览设置 PreviewSize预览大小 Priority优先 ProgressDialog处理对话框 RecordDelimitation记录边界 RedChannelRed通道 Rename改名 RenderCamera渲染相机 RenderOptions渲染参数 RenderPreview渲染预览 RenderSettings:渲染设置: RenderTimeMasks渲染果罩框 RenderingProgress:渲染处理: SceneEventControl场景事件控制 SceneOptions场景参数 SceneRange场景范围 SceneStatistics:场景统计: SelectFilterMask选择过滤罩框 SelectImageFiletoFit选择适配图象 SelectImageInputDevice选择图象输出设备 SelectMaskImage选择罩框图象 Sequence队列 Size大小 Sounds声音 StandardChannels标准通道 Status状态 SystemUnitScale系统单位比例 TargetPath目标路径 TimeOutput时间输入 U/IParametersU/I参数 UIDisplay界面显示 UseStandinImage使用标准图象 VideoPostParameters视频合成参数 View视图 View视图 ViewFile察看文件 VRML97ExporterVRML97输出器 WorkingFilePrefix工作文件前缀 ZBufferZ缓冲 Iterations:重复数: ofLinksUp:链: fromend从结束 fromstart从开始 AlongPath:跟随路径: Holes:孔洞率: ofMelt:熔化率: ofTargetImage%ofTargetImage Selected被选择 Across\tAlt+RightArrow交差(A)\tAlt+RightArrow Activate\tCtrl-A活动(A)\tCtrl-A Align对齐(A) All所有(A) Allow同意(A) Antialiasing反锯齿(A) Array...阵列... AssigntoSelectedJobs分给指定工作(A) Attach连接(A) AttachIGESTraceInfo连接IGES轨迹信息(A) AttemptSingleShape尝试单图形(A) AutomaticSearch自动搜索(A) AutoscrollList自动卷动列表(A) Auto-smooth自动光滑(A) Auto-Smooth自动光滑(A) BackgroundColour..背景色..(B) Bezier-Smooth贝塞尔光滑(B) Bitmap位图(B) Bottom\tCtrl+DownArrow底(B)\tCtrl+DownArrow BoundedSurface(IGESType143)边定曲面(B)(IGES类型143) BrowseFilter浏览过滤器(B) Browse...浏览(B)... CalculateShadows计算阴影(C) CameraSettings..相机设置(C) Cameras相机(C) Cancel取消(C) Category:目录(C) CenterinDialog对话框中心(C) Clone复制(C) Close关闭(C) Color颜色(C) Combine联合(C) Comments备注(O) ConfigurePaths...设置路径(C)... Connect连接(C) ConnecttoSupportandInformation...联系支持与信息(C)... Connect...\tCtrl-O连接(C)..\tCtrl-O ConvertLevelsToGroups转换层级为组(C) Convertunits转换单位(C) Copy复制(C) CopyMaps...复制贴图(B)... CopyObject复制对象(Y) Copy\tCtrl+C复制\tCtrl+C Corner角点(C) CreateServerGroup...创建服务器组(C)... Crossing交差(C) CurveTolerance:曲线误差(C): CustomParameters..自定义参数(C) Customize自定义(C) Cut剪切(C) DeactivateAllMaps取消激活所有视图(D) Debug编译(D) Defer延期(D) Delete删除(D) Description说明(D) Detach分离(D) Deviceselection设备选择(D) Diffuse漫反射(D) Disallow不同意(D) Disconnect\tCtrl-X取消连接(D)\tCtrl-X Display显示(D) DisplayFloater...显示面板(D)... Document\nContents:文件内容(D): Don'tshowthisagain不再显示(D) Down\tAlt+UpArrow下(D)\tAlt+UpArrow Edit编辑(E) EditEvent...\tCtrl+E编辑事件(E)...\tCtrl+E EditNamedSelections...编辑命名选择集(E)... EditRollout\tF2编辑卷动(E)\tF2 EditSettings...\tCtrl-J修改设置(E)...\tCtrl-J EndSession结束(E) Entity实体(E) EntityValidation实体确认(E) Environment...环境(E) EvaluateAll\tCtrl+E全部求值(E)\tCtrl+E ExpertMode专业模式((E) Explode炸开(E) Fetch取回(F) FindMaps查找贴图(F) Find...\tCtrl+F查找(F)...\tCtrl+F FlashLight闪光灯(F) Flip镜像(F) Folders:文件夹(F): FontSize字体大小(F) ForceFeebackSettings..回放设置(F).. Geometry几何体(G) GridandSnapSettings...网格和捕捉设置(G)... Group成组(G) GuideSettings...向导设置(G)... Height高度(H) Helpers辅助对象(H) Hold保持(H) Horizontal\tCtrl+Shift+F9水平(H)\tCtrl+Shift+F9 Horz.Center\tShift+F9水平中心(H)\tShift+F9 IgnoreInvalidEntities忽略无效实体(I) IgnoreScenePath忽略场景路径(I) IncludeStartFile包括开始文件(I) IndependentConstituents关联组成(I) Instance关联(I) Intersection相交(I) Invert反选(I) Jobs工作(J) Keywords关键词(K) Large大(L) Layout布局(L) Learning3dsmax...学习3dsmax(L)... Left\tCtrl+LeftArrow左(L)\tCtrl+LeftArrow Lights灯光(L) Load装入(L) LoadCustomUI...装载定制UI(L)... LogSettings记录设定(l) MacroRecorder宏记录(M) MacroRecorder宏记录(M) MakePreview...创建预览(M) MakeSameSize相同大小(M) Manager管理(M) MapPointEntities贴图点实体(M) MatchCameratoView使摄像机与视图匹配(M) MAXGrouping最大组(M) MAXScriptMAX脚本(M) Mergeobjectswithcurrentdesign.合并物体到当前设计(M). Mergeobjectswithcurrentscene.合并物体到当前场景. Merge...合并(M)... Mirror...镜像(M)... Mixvertexcolors混合顶点颜色(M) Mode模式(M) Modify...修改(M)... Move移动(M) MultipleObjects多个物体(M) NearestBigCity最近的大城市(N) NewParticleView新建粒子视图(N) NewRollout新建卷动(N) NewSchematicView新建图解视图(N) NewScript新建脚本(N) NewTrackView新建轨迹视图(N) New\tCtrl+N新建(N)\tCtrl+N Next下一步(N) NormalAlign...法线对齐(N)... Object物体(O) OpenParticleView打开粒子视图(O) OpenSchematicView打开图解视图(O) OpenScript...打开脚本(O)... OpenTrackView打开轨迹视图(O) Organization:组织(O): Paste粘贴(P) Paste\tCtrl+V粘贴(P)\tCtrl+V Play/Pause播放/暂停(P) Plug-inInformation...插件信息(P)...... PointTolerance:点误差(P): Preferences...参数设定(P)... Properties...属性(P)... Properties...\tCtrl-Enter属性(P)...\tCtrl-Enter Properties:属性(P): Readonly只读(R) Receiver'sProductID:接受器产品ID(R): Redo重做 RedoViewChange重做视图改变(R) ReferenceObject参考对象(R) Refresh刷新(R) Remove删除(R) RemoveDoubleFaces删除双面(R) RemoveFromSelectedJobs从已选择工作中删除(R) RemovePath删除路径(R) Render...渲染(R) Rendering渲染性(R) RenderingSubsystem渲染子系统(R) RequestQueueControl\tCtrl-Q请求队列控制(R)Ctrl-Q Reset重设(R) RestartJob重启工作(R) ReverttoStartupUILayout恢复到启动时的UI布局(R) Right\tCtrl+RightArrow右(R)\tCtrl+RightArrow RunScript...运行脚本(R)... Save保存(S) SaveActive%sView保存激活%s视图 SaveActiveView保存激活视图(S) SaveasDefaults另存为默认值(S) SaveAs...\tCtrl+S另存为(S)...\tCtrl+S Save\tCtrl+S保存(S)\tCtrl+S Save...\tCtrl+S保存(S)...\tCtrl+S SceneLights场景灯(S) SchematicView图解视图(S) Search搜索(S) SelectAll\tCtrl+A全部选择(S)tCtrl+A Select...选择(S) SelectionFloater...选择面板... Sender'sProductID:发送器产品ID(S): Servers服务器(S) Settings...设置(S)... Shapes图形(S) ShowLastRendering显示上次渲染图象(S) ShutDownManager...关闭管理器(S)... Shutdown退出(S) Simulation模拟器(S) SingleCurve(Approximations)单曲线(近似)(S) SingleObject单个物体(S) Skip跳过(S) SkipOutputTest忽略输出测试(K) Small小(S) Smooth光滑(S) Smooth-angle:光滑角度(S) SpaceEvenly空间均匀(S) Specify指定(S) StatusBar状态条(S) StripSelectedPaths删除选择路径(S) Subject:主题(S) Submit提交(S) Subtract(A-B)减去(A-B)(S) Surfacedeviation:表面细分(D) Suspend\tCtrl-S休眠(S)\tCtrl-S Test测试(T) Title:标题(T): Toolbar工具条(T) Top\tCtrl+UpArrow顶(T)\tCtrl+UpArrow TrackView轨迹视图(T) Transfer变换(T) TransformType-In...键盘输入变换(T)... TrimmedSurface(IGESType144)剪切曲面(T)(IGES类型144) Tutorials教材(T) Type:类型(T): UndoViewChange撤消视图改变(U) Ungroup解散(U) Unifynormals统一法线(U) UnifyNormals统一法线(U) UnitsSetup...单位设定(U)... UseAllServers使用所有服务器(U) UseAlphaPlane使用Alpha平面(U) UseIGESTolerance使用IGES误差(U) UserReference...用户手册(U)... Value:值(V): Vert.Center\tF9垂直中心(V)\tF9 Vertical\tCtrl+F9垂直(V)\tCtrl+F9 VideoPost...视频后处理(V) View视图(V) ViewBitmap查看位图(V) ViewFile...浏览文件(V)... ViewportConfiguration...视口设置(V)... Views视图(V) VirtualFrameBuffer虚拟帧缓冲 WeekSchedule...周计划(W)... Weld焊接(W) Width宽度(W) Window窗口(W) XRefs外部引用(X) 2Dmaps二维贴图 2DShaper二维图形 2DSnapToggle2D捕捉锁定开关 2DView2D视图 2-Rail双扶手 2-RailSweepSurface双扶手曲面 2-Sided双面 2x2x2FreeFormDeformationModifier2x2x2自由变形编辑器 3.Entertheauthorizationcode.3.输入授权码. 3DEditor三维编辑 3DLofter三维放样 3DMapSampleScale:三维贴图示例比例: 3Dmaps程序类贴图 3DSnapToggle3维捕捉锁定开关 3DStudioVIZFileFinder.3DStudioVIZ文件查找器. 3DSImport3DS输入

nodejs可以接受tcp服务器的数据吗

nodejs中我们使用net模块来创建tcp服务器,tcp客户端,实现服务器与客户端之前的数据通信

创建tcp服务器

var server=net.createServer([optations],[connectionListener])

optations:{allowHalfOpen:boolean}

allowHalfOpen:false 当服务器接受到客户端发送的一个FIN包时候,会回发一个FIN包,当为true时服务器不会回FIN包,使得tcp服务器可以继续发送数据到客户端,但是不会接受客户端发送的数据,开发者必须调动end方法来关闭socket,默认是false

connectionListener:当客户端与服务器连接上了,可以触发的回调函数。

function(socket){

//.......

}

我们也可以不用回调函数来写连接上做什么处理,连接上会触发connection事件

var server=net.createServer()返回创建的tcp服务器

我们可以server.on('connection',function(socket){

})

在创建完tcp服务器我们通知服务器要监听客户端连接

server.listen(port,[host],[backlog],[callback])

port:监听的端口,为0时候tcp服务器分配一个随机的端口

host:监听的ip和主机名,省略该参数,服务器监听任何ipv4地址的客户端连接

backlog:指定等待队列中最大的客户端连接最大数量 默认511

当指定端口、ip这个时候服务器开始监听这个ip这个端口的客户端了,这个时候触发listening事件,可以指定callback参数来处理触发listening具体要做什么

我们也可以

server.on('lisening',function(){

//.......

})

创建一个tcp服务器后可以用server.address()查看tcp服务器监听的信息

var address=server.address()

addres是一个对象

prot :监听的端口

address:监听的ip

family:ipv4还是ipv6

我们可以使用getConnections()查看与服务器连接的客户端的数量

server.getConnections(callback)

callback:function(err,count){

}

err:错误信息

count:为连接服务器的数量

我们也可以设置最大的连接数,超过这个数字,服务器不允许连接

server.maxConnections=2

服务器关闭

server.close([callback])

这个 方法让tcp服务器拒绝新的客户端连接,原有已经连上的客户端是不关闭的,当所有的连接服务器的客户端关闭时候,服务器默认自动关闭,触发服务器的close事件

下面我们写一个tcp服务器

var net=require("net");

opations={allowHalfOpne:false}

var server=net.createServer(opations);

server.on('connection',function(socket){

server.maxConnections=2;

console.log("服务器最大连接数为%s",server.maxConnections)

server.getConnections(function(err,count){

console.log("已经有%s个客户端连接",count)

})

console.log("%s客户端与服务器建立连接",server.address().address)

})

server.on('error',function(err){

throw err;

})

server.on('listening',function(){

console.log("服务器开始监听%j",server.address())

console.log("服务器开始监听")

})

server.listen(9966,'192.168.0.3');

setTimeout(function(){

server.close(function(){

console.log("tcp服务器关闭11111")

})

console.log("tcp服务器关闭")

},20000)

注意连接成功的时候触发的connection事件,执行的方法,参数是一个socket端口对象,这个就是服务器所监听的端口对象,所以我们socket.address().address返回给我们的是监听ip

socket端口对象

port:端口

address:ip

family:ipv4 ipv6

socket端口对象,可以读取客户端发送的流数据,每次接收到客户端发送的数据触发data事件。

接受客户端发送的消息(在连接成功的触发函数中 让server监听data事件做相应的处理)

server.on('connection',function(socket){

socket.on('data',function(data){

socket.setEncoding("utf-8");

console.log(data)

//console.log(data.toString())

})

})

bytesRead为socket端口对象监听客户端发送的数据字节数

console.log(socket.bytesRead)

当客户端关闭时候,触发socket端口对象的end事件

我们把客户端连接发送的数据保存到一个文件下

var net=require("net");

var fs=require("fs");

var server =net.createServer();

var op={

flags:"a",

encoding:"utf-8"

}

var file=fs.createWriteStream('./socket.txt',op)

server.on('connection',function(socket){

socket.on('data',function(data){

file.write(data);

})

})

server.on('listening',function(){

console.log("监听开始")

})

server.listen('1111','192.168.0.3')

以管道形式发送数据到文件

var net=require("net");

var fs=require("fs");

var server =net.createServer();

var op={

flags:"a",

encoding:"utf-8"

}

var file=fs.createWriteStream('./socket.txt',op)

server.on('connection',function(socket){

//socket.on('data',function(data){

// file.write(data);

//})

socket.pipe(file,{end:false});

socket.on("end",function(){

file.end("wanbi")

})

})

server.on('listening',function(){

console.log("监听开始")

})

server.listen('1111','192.168.0.3')

tcp客户端

创建tcp客户端

var client =new net.socket([opations])

optation:fd 一个现有的socket端口对象文件描述

type :ipv4 、ipv6

allowHalfOpne:true、false

连接服务器

client.connect(prot,[host],[callback])

host不指定默认为本地ip

回调函数表示连接上了做什么

若没有可以socket端口对象触发connect事件

client.on("connect",function(){

})

当我们连接成功后客户端服务器端的socket端口对象有下面的属性

remoteAddress、remotePort、localAddress、localPort

socket端口对象可以写入服务器、客户端流数据

socket.write(data,[encodeing],[callback])

写入数据少时候我们直接写入缓存区,数据很多时候,缓存区满了,我们要把数据写入缓存队列中,这个时候write(data) 返回false,触发drain

我们可以用bufferSize看缓存队列中有多少个字节

socket.on("error",function(err){

})

当遇到error时候这个socket端口对象应该销毁

socket.destory()

socket.end([data],[encoding])

这个方法表示我们要关闭socket端口对象,这个不是关闭服务器的close方法,后者是关闭服务器,实现的效果是不能让客户端连接了,前者是关闭连接(socket端口对象)

当我们使用服务器的socket端口对象(连接客户端得)的end(data,encoding)方法时候,会触发客户端socket端口对象end事件

服务器:

socket.end('88');

客户端会执行下面的代码:

client.on("end",function(){

//......

})

服务器端不会退出应用程序,即使所有的客户端都断开了,这个时候我们要server.unref(),退出程序,可以用server.ref()阻止程序退出.

当socket端口对象彻底关闭时候会触发close事件,我们可以指定当端口对象关闭时候做的处理

socket.on(''close',faction(had_error){

if(had_error){}

else{}

})

socket.writtenBytes表示写了多少个字节

我们tcp服务器与客户端连接了,但是突然间有一个断电了,来不及向另一端发送关闭连接的FIN包,这样另一边这个socket端口永远处于连接状态,我们用socket.setKeepAlive([enable],[inteval])定时向另一端发送监测包,

我们实现一个服务器读一个文件的信息,当有客户单连接上,吧这个信息传给客户端,输出在控制台

服务器代码

var net=require("net");

var fs=require("fs");

var server =net.createServer();

var op={

flags:"r",

encoding:"utf-8"

}

var file=fs.createReadStream('./socket.txt',op)

server.on('connection',function(socket){

file.on('data',function(data){

socket.write(data);

})

socket.on("end",function(){

file.end("wanbi")

})

})

server.on('listening',function(){

console.log("监听开始")

})

server.listen('1111','192.168.0.3')

客户端代码

var net=require("net");

var client=new net.Socket();

client.connect(1111,'192.168.0.3')

client.on('connect',function(){

console.log("ok")

})

client.on("data",function(data){

console.log(data.toString())

})

如何自己检查NodeJS的代码是否存在内存泄漏

首先,我们来看一个简单的内存泄漏

var http = require('http');var server = http.createServer(function (req, res) {

for (var i=0; i1000; i++) {

server.on('request', function leakyfunc() {});

}

res.end('Hello World\n');}).listen(1337, '127.0.0.1');server.setMaxListeners(0);console.log('Server running at . Process PID: ', process.pid);

每一个请求我们增加了1000个导致泄漏的监听器。如果我们在一个shell控制台中执行以下命令:

while true; do curl ; done

然后在另外一个shell控制台中查看我们的进程

top -pid

我们会看到node进程产生异常高的内存占用,我们的node进程看起来失控了。那么,当我们的node进程出现这种情况的时候,通常我们该怎样诊断出问题的根源?

内存泄露的检测

npm模块 memwatch 是一个非常好的内存泄漏检查工具,让我们先将这个模块安装到我们的app中去,执行以下命令:

npm install --save memwatch

然后,在我们的代码中,添加:

var memwatch = require('memwatch');memwatch.setup();

然后监听 leak 事件

memwatch.on('leak', function(info) {

console.error('Memory leak detected: ', info);});

这样当我们执行我们的测试代码,我们会看到下面的信息:

{

start: Fri Jan 02 2015 10:38:49 GMT+0000 (GMT),

end: Fri Jan 02 2015 10:38:50 GMT+0000 (GMT),

growth: 7620560,

reason: 'heap growth over 5 consecutive GCs (1s) - -2147483648 bytes/hr'}

memwatch发现了内存泄漏!memwatch 判定内存泄漏事件发生的规则如下:

当你的堆内存在5个连续的垃圾回收周期内保持持续增长,那么一个内存泄漏事件被派发

了解更加详细的内容,查看?memwatch

内存泄漏分析

使用memwatch我们发现了存在内存泄漏,这非常好,但是现在呢?我们还需要定位内存泄漏出现的实际位置。要做到这一点,有两种方法可以使用。

memwatch heap diff

通过memwatch你可以得到堆内存使用量和内存随程序运行产生的差异。详细的文档在这里

例如,我们可以在两个leak事件发生的间隔中做一个heap dump:

var hd;memwatch.on('leak', function(info) {

console.error(info);

if (!hd) {

hd = new memwatch.HeapDiff();

} else {

var diff = hd.end();

console.error(util.inspect(diff, true, null));

hd = null;

}});

执行这段代码会输出更多的信息:

{ before: {

nodes: 244023,

time: Fri Jan 02 2015 12:13:11 GMT+0000 (GMT),

size_bytes: 22095800,

size: '21.07 mb' },

after: {

nodes: 280028,

time: Fri Jan 02 2015 12:13:13 GMT+0000 (GMT),

size_bytes: 24689216,

size: '23.55 mb' },

change: {

size_bytes: 2593416,

size: '2.47 mb',

freed_nodes: 388,

allocated_nodes: 36393,

details:

[ { size_bytes: 0,

'+': 0,

what: '(Relocatable)',

'-': 1,

size: '0 bytes' },

{ size_bytes: 0,

'+': 1,

what: 'Arguments',

'-': 1,

size: '0 bytes' },

{ size_bytes: 2856,

'+': 223,

what: 'Array',

'-': 201,

size: '2.79 kb' },

{ size_bytes: 2590272,

'+': 35987,

what: 'Closure',

'-': 11,

size: '2.47 mb' },...

所以在内存泄漏事件之间,我们发现堆内存增长了2.47MB,而导致内存增长的罪魁祸首是闭包。如果你的泄漏是由某个class造成的,那么what字段可能会输出具体的class名字,所以这样的话,你会获得足够的信息来帮助你最终定位到泄漏之处。

然而,在我们的例子中,我们唯一获得的信息只是泄漏来自于闭包,这个信息非常有用,但是仍不足以在一个复杂的应用中迅速找到问题的来源(复杂的应用往往有很多的闭包,不知道哪一个造成了内存泄漏——译者注)

所以我们该怎么办呢?这时候该Heapdump出场了。

Heapdump

npm模块node-heapdump是一个非凡的模块,它可以使用来将v8引擎的堆内存内容dump出来,这样你就可以在Chrome的开发者工具中查看问题。你可以在开发工具中对比不同运行阶段的堆内存快照,这样可以帮助你定位到内存泄漏的位置。要想了解heapdump的更多内容,可以阅读这篇文章

现在让我们来试试 heapdump,在每一次发现内存泄漏的时候,我们都将此时的内存堆栈快照写入磁盘中:

memwatch.on('leak', function(info) {

console.error(info);

var file = '/tmp/myapp-' + process.pid + '-' + Date.now() + '.heapsnapshot';

heapdump.writeSnapshot(file, function(err){

if (err) console.error(err);

else console.error('Wrote snapshot: ' + file);

});});

运行我们的代码,磁盘上会产生一些.heapsnapshot的文件到/tmp目录下。现在,在Chrome浏览器中,启动开发者工具(在mac下的快捷键是alt+cmd+i),点击Profiles标签并点击Load按钮载入我们的快照。

我们能够很清晰地发现原来leakyfunc()是内存泄漏的元凶。

我们依然还可以通过对比两次记录中heapdump的不同来更加迅速确认两次dump之间的内存泄漏:

想要进一步了解开发者工具的memory profiling功能,可以阅读?Taming The Unicorn: Easing JavaScript Memory Profiling In Chrome DevTools?这篇文章。

Turbo Test Runner

我们给Turbo?-?FeedHenry开发的测试工具提交了一个小补丁 — 使用了上面所说的内存泄漏检查技术。这样就可以让开发者写针对内存的单元测试了,如果模块有内存问题,那么测试结果中就会产生相应的警告。详细了解具体的内容,可以访问Turbo模块。

结论和其他细节

上面的内容讨论了一种检测NodeJS内存泄漏的基本方法,以下是一些结论:

heapdump有一些潜规则,例如快照大小等。仔细阅读说明文档,并且生成快照也是比较消耗CPU资源的。

还有些其他方法也能生成快照,各有利弊,针对你的项目选择最适合的方式。(例如,发送sigusr2到进程等等,这里有一个memwatch-sigusr2项目)

需要考虑在什么情况下开启memwatch/heapdump。只有在测试环境中有开启它们的必要,另外也需要考虑heapdump的频度以免耗尽了CPU。总之,选择最适合你项目的方式。

也可以考虑其他的方式来检测内存的增长,比如直接监控process.memoryUsage()是一个可以考虑的方法。

当内存问题被探测到之后,你应该要确定这确实是个内存泄漏问题,然后再告知给相关人员。

当心误判,短暂的内存使用峰值表现得很像是内存泄漏。如果你的app突然要占用大量的CPU和内存,处理时间可能会跨越数个垃圾回收周期,那样的话memwatch很有可能将之误判为内存泄漏。但是,这种情况下,一旦你的app使用完这些资源,内存消耗就会降回正常的水平。所以,你其实需要注意的是持续报告的内存泄漏,而可以忽略一两次突发的警报。

memwatch目前仅支持node 0.10.x,node 0.12.x(可能还有io.js)支持的版本在这个分支

刚学习nodejs,请高手帮助解答

您好,尊敬的WOPHP开源程序,很高兴回答您的问题。

刷新一次一下子加了2,说明一定是浏览器发出了两次请求。这个是和浏览器的机制有关的。和你写的程序没有关系。你用的是chrome内核的浏览器吧,微软的edge就没有你说的这个问题。

浏览器有时候不是一次性把所有的数据都取到的,有时候会分开读数据,为了是网页能够快速打开,不影响人们的使用。比如chrome浏览器第一次读页面数据,然后第二次在请求像ico图标(chrome浏览器会有这种独特的要求,如第一次请求的地址是,然后浏览器会再次发一个的请求来请求网页图标)这样的无关紧要的数据。或者说这两次请求是并行发出。而微软的浏览器则没有这个问题。

以上是我瞎猜的。希望我的答案能让你满意。谢谢观赏,马上就要过年了,祝你新年万事如意。

(责任编辑:IT教学网)

更多

推荐淘宝营销文章