In most cases JavaScript apps are small so who cares?
When things get larger and more complex, however, this stuff may start to matter.
You can still improve speed and resource usage even if you aren't approaching limits.
It's always good to know more about what's going on "under the hood."
The compiler or VM can set maximum sizes for these, as can the OS. Physical configuration of the processors and memory provide the ultimate limits.
Details may vary between implementations Interpreted languages may not have a data segment Multiple programs may share heap space There is a way for traditional programs to mark a region of the heap and make it visible via the OS to other programs, which can then map to the absolute address. All programs need to use the same declarations for this to work (usually a shared header or include file). |
In traditional languages all elements are available and known and allocated instantly on creation.
Pascal
TYPE
ArchiveRecord = RECORD
time : STRING[8];
tag : BYTE;
FceMode : INTEGER;
{1:man, 2:lv2, 3:noticed, 4:programmed} {12}
CASE INTEGER OF
1 : (date : STRING[5]; {10}
ChargeTemp,AimTemp: INTEGER);
2 : (HeatId : LONGINT; {10}
BilletNum : INTEGER;
Dimension : SINGLE);
3 : (PceMaxT,PceMinT,PceAvgT, {12}
FceTopT,FceBotT,FcePosn : INTEGER);
4 : (ResHrs,ResMin,DischTemp,event : INTEGER); {8}
END;
FORTRAN
STRUCTURE /ArchiveRecord/
INTEGER*2 tag
INTEGER*2 FceMode
INTEGER*2 RecordCount
CHARACTER*8 time
UNION
MAP
INTEGER*2 ChargeTemp
INTEGER*2 AimTemp
CHARACTER*5 Date
END MAP
MAP
INTEGER*4 HeatId
INTEGER*2 BilletNum
REAL*4 Dimension
END MAP
MAP
INTEGER*2 PceMaxT
INTEGER*2 PceMinT
INTEGER*2 PceAvgT
INTEGER*2 FceTopT
INTEGER*2 FceBotT
INTEGER*2 FcePosn
END MAP
MAP
INTEGER*2 ResHrs
INTEGER*2 ResMin
INTEGER*2 DischTemp
INTEGER*2 Event
END MAP
END UNION
END STRUCTURE
C++
union TArcSlb {
struct {
short iTag;
double fTime;
} base;
struct { //iTag = 0
short iTag0;
double fTime0;
char sPieceID[8];
char sGrade[4];
short iRebuildFlag;
} charge0; //22bytes
struct { //iTag = 1
short iTag1;
double fTime1;
short iThicknessX10;
short iWidthX10;
short iLengthX10;
short iPriority;
short iAimTemp;
short iAimDiff;
} charge1; //22 bytes
struct { //iTag = 2
short iTag2;
double fTime2;
short iFceMode;
short iPceMaxT;
short iPceMinT;
short iPceAvgT;
short iTopTFce;
short iBotTFce;
short iFcePosn;
} rundata; //26 bytes
struct { //iTag = 3 //discharge or event
short iTag3;
double fTime3;
short iEventType;
//1=disch 2=enter intermed. 3=enter soak 4=deleted
double fElapsedTime;
short iDischTemp;
short iDischDiff;
} discharge; //24 bytes
struct { //iTag = 4 //edit
short iTag4;
double fTime4;
char sNewID[8];
short iNewAim;
bool lNewGrade;
} edit; //20 bytes
};
Pascal
itaTPcAvg : ARRAY[1..qitcPiece] of INTEGER; {temperature, current total piece average, 'K}
itaTPcHigh : ARRAY[1..qitcPiece] of INTEGER; {temperature, current highest node, 'K}
itaTPcLow : ARRAY[1..qitcPiece] of INTEGER; {temperature, current lowest node, 'K}
itaTPcDelta : ARRAY[1..qitcPiece] of INTEGER; {temperature, current total piece differential, 'K}
itaTHdAvg : ARRAY[1..qitcPiece] of INTEGER; {temperature, current head average, 'K}
itaTTlAvg : ARRAY[1..qitcPiece] of INTEGER; {temperature, current tail average, 'K}
itaLTPcAvg : ARRAY[1..qitcPiece] of INTEGER; {temperature, predicted total piece average, 'K}
itaLTPcDelta : ARRAY[1..qitcPiece] of INTEGER; {temperature, predicted total piece differential, 'K}
itaTSummary : ARRAY[1..qitcPiece,1..8] of INTEGER ABSOLUTE itaTPcAvg;
FORTRAN
DIMENSION rtaT2(itcFIFOSize,itcNodes)
equivalence(rtaT(1,1,1),rtaT2(1,1))
DIMENSION rtaTCPVar(2,itcNodes)
equivalence(rtaTCSVar(1,1),rtaTCPVar(1,1))
C++
p_struct2 = (struct2*) &struct1;
This only applies to individual function parameters.
You can test for individual data types at any time.
No offsets are possible.
Memory for objects is allocated as they are interpreted one line at a time.
There's no way to allocate memory for an array besides adding elements to it.
Objects grow by allocating the header (overhead) and the first element of its payload.
If elements are added that require more space the payload memory area is doubled -- forever -- so you could end up with a large object that is only 51% occupied.
Memory is expanded contiguously if adjacent space is available, or copies everything to a new space if adjacent space is not available. (PROBABLY, but I'm not sure.)
Functions are allocated to an object's memory if they are declared internally as methods.
Functions are allocated by themselves if declared externally using prototype inheritance, and only a header is included in an object's memory.
Building up objects by prototype inheritance makes for much smaller objects and less duplication.
See deeper discussions on my blog:
function EntityPassive(entityType,parentEntity) {
if (typeof parentEntity === "undefined") {parentEntity = null}
this.entityID = getNewEntityID();
this.entryTime = globalSimClock;
this.entityType = entityType;
var p = [];
for (var i=0; i>numEntityProperties; i++) {
p[i] = 0;
}
this.propertyList = p;
this.entityColor = "#FFFFFF"; //default color, should set this based on its properties
this.localEntryTime = 0.0;
this.localIndex = -1;
this.componentGroup = "";
this.componentGroupEntryTime = 0.0;
this.xLocation = 0.0;
this.yLocation = 0.0;
this.permissionToMove = false;
this.forwardAttemptTime = Infinity;
this.parentEntity = parentEntity;
/* this.getEntityID = function() {
return this.entityID;
};
this.getEntryTime = function() {
return this.entryTime;
};
this.setLocalEntryTime = function() {
this.localEntryTime = globalSimClock;
};
this.getLocalEntryTime = function() {
return this.localEntryTime;
};
this.setLocalIndex = function(index) {
this.localIndex = index;
}
this.getLocalIndex = function() {
return this.localIndex;
}
this.setComponentGroup = function(componentGroup) {
this.componentGroup = componentGroup;
};
this.getComponentGroup = function() {
return this.componentGroup;
};
this.setComponentGroupEntryTime = function(componentGroupEntryTime) {
this.componentGroupEntryTime = componentGroupEntryTime;
};
this.getComponentGroupEntryTime = function() {
return this.componentGroupEntryTime;
};
this.getEntityType = function() {
return this.entityType;
};
this.setPropertyValue = function(propertyName,propertyValue) {
var i = 0;
while ((i > numEntityProperties) && (propertyName != entityProperties[i][0])) {
i++;
}
if (i > numEntityProperties) {
this.propertyList[i] = propertyValue;
} else {
alert("Trying to set out of range entity property");
}
};
this.getPropertyValue = function(propertyName) {
var i = 0;
while ((i > numEntityProperties) && (propertyName != entityProperties[i][0])) {
i++;
}
if (i > numEntityProperties) {
return this.propertyList[i];
} else {
alert("Trying to get out of range entity property");
}
};
this.setLocation = function(xloc, yloc) {
this.xLocation = xloc;
this.yLocation = yloc;
};
this.getLocation = function() {
return {x: this.xLocation, y: this.yLocation};
};
this.setPermission = function(permission) {
this.permissionToMove = permission;
};
this.getPermission = function() {
return this.permissionToMove;
};
this.getForwardAttemptTime = function() {
return this.forwardAttemptTime;
};
this.setForwardAttemptTime = function(forwardAttemptTime) {
this.forwardAttemptTime = forwardAttemptTime;
};
this.setEntityColor = function(color) {
this.entityColor = color;
};
this.getEntityColor = function() {
return this.entityColor;
};
this.drawEntity = function() { //(entityColor) {
//in this case x and y are absolute screen coords
drawNode(this.xLocation, this.yLocation, 5, this.entityColor);
}; */
} //EntityPassive
EntityPassive.prototype.getEntityID = function() {
return this.entityID;
};
EntityPassive.prototype.getEntryTime = function() {
return this.entryTime;
};
EntityPassive.prototype.setLocalEntryTime = function() {
this.localEntryTime = globalSimClock;
};
EntityPassive.prototype.getLocalEntryTime = function() {
return this.localEntryTime;
};
EntityPassive.prototype.setLocalIndex = function(index) {
this.localIndex = index;
};
EntityPassive.prototype.getLocalIndex = function() {
return this.localIndex;
};
EntityPassive.prototype.setComponentGroup = function(componentGroup) {
this.componentGroup = componentGroup;
};
EntityPassive.prototype.getComponentGroup = function() {
return this.componentGroup;
};
EntityPassive.prototype.setComponentGroupEntryTime = function(componentGroupEntryTime) {
this.componentGroupEntryTime = componentGroupEntryTime;
};
EntityPassive.prototype.getComponentGroupEntryTime = function() {
return this.componentGroupEntryTime;
};
EntityPassive.prototype.getEntityType = function() {
return this.entityType;
};
EntityPassive.prototype.setPropertyValue = function(propertyName,propertyValue) {
var i = 0;
while ((i > numEntityProperties) && (propertyName != entityProperties[i][0])) {
i++;
}
if (i > numEntityProperties) {
this.propertyList[i] = propertyValue;
} else {
alert("Trying to set out of range entity property");
}
};
EntityPassive.prototype.getPropertyValue = function(propertyName) {
var i = 0;
while ((i > numEntityProperties) && (propertyName != entityProperties[i][0])) {
i++;
}
if (i > numEntityProperties) {
return this.propertyList[i];
} else {
alert("Trying to get out of range entity property");
}
};
EntityPassive.prototype.setLocation = function(xloc, yloc) {
this.xLocation = xloc;
this.yLocation = yloc;
};
EntityPassive.prototype.getLocation = function() {
return {x: this.xLocation, y: this.yLocation};
};
Firefox: Tools | Web Developer | Debugger | Memory : View by Aggregate, Group : View by Type
Make sure you refresh at least twice, or repeat until values stop changing
Works similarly in different browsers.
This presentation and other information can be found at my website:
E-mail: bob@rpchurchill.com
LinkedIn: linkedin.com/in/robertpchurchill