JavaScript 개체의 크기를 가져오려면 어떻게 해야 합니까?
JavaScript 객체가 차지하는 크기를 알고 싶습니다.
다음 기능을 수행합니다.
function Marks(){
this.maxMarks = 100;
}
function Student(){
this.firstName = "firstName";
this.lastName = "lastName";
this.marks = new Marks();
}
'I'm '를 인스턴스화합니다.student
:
var stud = new Student();
그런 걸 할 수 있게
stud.firstName = "new Firstname";
alert(stud.firstName);
stud.marks.maxMarks = 200;
기타.
이제 ㅇㅇ, ㅇㅇ.stud
오브젝트는 메모리에서 일정 크기를 차지합니다.여기에는 약간의 데이터와 더 많은 개체가 있습니다.
용량을 확인하려면 어떻게 요?stud
체가가 점유 ?? ????랄까...sizeof()
JavaScript? 한 알수 정말 것 요.sizeof(stud)
.
몇 달 동안 인터넷을 검색했는데 찾을 수가 없었어요. (몇 군데 포럼에서 물어봤지만 답변이 없었어요.)
나는 원래의 답변에 코드를 다시 반영했다.재귀와 추정된 존재 오버헤드를 제거했습니다.
function roughSizeOfObject( object ) {
var objectList = [];
var stack = [ object ];
var bytes = 0;
while ( stack.length ) {
var value = stack.pop();
if ( typeof value === 'boolean' ) {
bytes += 4;
}
else if ( typeof value === 'string' ) {
bytes += value.length * 2;
}
else if ( typeof value === 'number' ) {
bytes += 8;
}
else if
(
typeof value === 'object'
&& objectList.indexOf( value ) === -1
)
{
objectList.push( value );
for( var i in value ) {
stack.push( value[ i ] );
}
}
}
return bytes;
}
Google Chrome Hip Profiler를 사용하면 객체 메모리 사용을 검사할 수 있습니다.
추적에서 객체를 찾을 수 있어야 하는데, 이는 까다로울 수 있습니다.개체를 Window global에 고정하면 "Containment" 목록 모드에서 쉽게 찾을 수 있습니다.
첨부된 스크린샷에서 윈도우에 "testObj"라는 오브젝트를 만들었습니다.그런 다음 (녹음을 한 후) 프로파일러에 위치하면 객체의 전체 크기 및 객체의 모든 것이 "유지 크기"로 표시됩니다.
위 스크린샷에서 개체는 보존 크기 60을 표시합니다.여기서 단위는 바이트인 것 같습니다.
나는 단지 비슷한 문제를 해결하기 위해 이 글을 썼다.이것은 당신이 찾고 있는 것, 즉 인터프리터가 오브젝트를 저장하는 방법을 고려하지 않습니다.
그러나 V8을 사용하는 경우 멋진 프로토타이핑 및 숨겨진 클래스가 오버헤드의 대부분을 차지하므로 근사치를 얻을 수 있습니다.
function roughSizeOfObject( object ) {
var objectList = [];
var recurse = function( value )
{
var bytes = 0;
if ( typeof value === 'boolean' ) {
bytes = 4;
}
else if ( typeof value === 'string' ) {
bytes = value.length * 2;
}
else if ( typeof value === 'number' ) {
bytes = 8;
}
else if
(
typeof value === 'object'
&& objectList.indexOf( value ) === -1
)
{
objectList[ objectList.length ] = value;
for( i in value ) {
bytes+= 8; // an assumed existence overhead
bytes+= recurse( value[i] )
}
}
return bytes;
}
return recurse( object );
}
서버에서 클라이언트로 전송될 가능성이 있는 매우 큰 오브젝트에 플래그를 붙이기 위해 이 플래그를 사용하는 경우가 있습니다.메모리 풋프린트를 나타내지 않습니다.보내거나 보관하는 데 드는 대략적인 비용만 얻을 수 있습니다.
또한 느린데, 개발 전용입니다.하지만 한 줄의 코드로 대략적인 답을 얻는 것은 나에게 도움이 되었다.
roughObjSize = JSON.stringify(bigObject).length;
다음은 이 문제에 대한 조금 더 간단한 해결 방법입니다.
const typeSizes = {
"undefined": () => 0,
"boolean": () => 4,
"number": () => 8,
"string": item => 2 * item.length,
"object": item => !item ? 0 : Object
.keys(item)
.reduce((total, key) => sizeOf(key) + sizeOf(item[key]) + total, 0)
};
const sizeOf = value => typeSizes[typeof value](value);
개체 크기를 가져오는 NPM 모듈이 있습니다. 이 모듈을 사용하여 설치할 수 있습니다.npm install object-sizeof
var sizeof = require('object-sizeof');
// 2B per character, 6 chars total => 12B
console.log(sizeof({abc: 'def'}));
// 8B for Number => 8B
console.log(sizeof(12345));
var param = {
'a': 1,
'b': 2,
'c': {
'd': 4
}
};
// 4 one two-bytes char strings and 3 eighth-bytes numbers => 32B
console.log(sizeof(param));
이것은 진부한 방법이지만, 다른 번호로 두 번 시도해보니 일관성이 있는 것 같습니다.
여러분이 할 수 있는 일은 여러분이 원하는 종류의 100만 개에서 200만 개 정도의 엄청난 수의 객체를 할당하는 것입니다.가비지 컬렉터가 개체를 해제하지 않도록 어레이에 개체를 배치합니다(배열로 인해 메모리 오버헤드가 약간 증가하지만 이 문제는 발생하지 않기를 바랍니다.게다가 개체가 메모리에 있는 것을 염려할 경우에는 개체를 어딘가에 저장합니다).할당 전후에 경고를 추가하고 각 경고에서 Firefox 프로세스가 사용하는 메모리 양을 확인합니다.테스트에서 페이지를 열기 전에 새로운 Firefox 인스턴스가 있는지 확인하십시오.페이지를 열고 "before" 경보가 표시된 후 메모리 사용량을 기록합니다.경고를 닫고 메모리가 할당될 때까지 기다립니다.오래된 메모리에서 새 메모리를 뺀 후 할당량으로 나눕니다.예를 들어:
function Marks()
{
this.maxMarks = 100;
}
function Student()
{
this.firstName = "firstName";
this.lastName = "lastName";
this.marks = new Marks();
}
var manyObjects = new Array();
alert('before');
for (var i=0; i<2000000; i++)
manyObjects[i] = new Student();
alert('after');
컴퓨터에서 시도해보니 "before" 경보가 표시되었을 때 프로세스 메모리가 48352K였습니다.할당 후 Firefox의 메모리는 440236K였습니다.200만 개의 할당에 대해서는, 이것은 각 오브젝트에 대해서 약 200 바이트입니다.
100만개의 할당으로 다시 시도해보니 오브젝트당 196바이트(어레이에 200만개의 추가 데이터가 사용되었을 것입니다)로 비슷합니다.
자, 여기 도움이 될 만한 해킹 방법이 있습니다.JavaScript는 "size of" 메서드를 제공하지 않습니다. 각 JavaScript 구현이 다르기 때문입니다.예를 들어 Google Chrome에서는 동일한 페이지가 각 개체에 대해 약 66바이트를 사용합니다(최소한 태스크 관리자에서 판단).
같은 문제를 안고 있다.구글에서 검색한 결과 stackoverflow 커뮤니티와 이 솔루션을 공유하고 싶습니다.
중요:
Github https://gist.github.com/zensh/4975495에서 Yan Ching이 공유한 기능을 사용했습니다.
function memorySizeOf(obj) {
var bytes = 0;
function sizeOf(obj) {
if(obj !== null && obj !== undefined) {
switch(typeof obj) {
case 'number':
bytes += 8;
break;
case 'string':
bytes += obj.length * 2;
break;
case 'boolean':
bytes += 4;
break;
case 'object':
var objClass = Object.prototype.toString.call(obj).slice(8, -1);
if(objClass === 'Object' || objClass === 'Array') {
for(var key in obj) {
if(!obj.hasOwnProperty(key)) continue;
sizeOf(obj[key]);
}
} else bytes += obj.toString().length * 2;
break;
}
}
return bytes;
};
function formatByteSize(bytes) {
if(bytes < 1024) return bytes + " bytes";
else if(bytes < 1048576) return(bytes / 1024).toFixed(3) + " KiB";
else if(bytes < 1073741824) return(bytes / 1048576).toFixed(3) + " MiB";
else return(bytes / 1073741824).toFixed(3) + " GiB";
};
return formatByteSize(sizeOf(obj));
};
var sizeOfStudentObject = memorySizeOf({Student: {firstName: 'firstName', lastName: 'lastName', marks: 10}});
console.log(sizeOfStudentObject);
당신은 그것에 대해 어떻게 생각하세요?
코멘트를 하지 못해 죄송하고, 저는 그냥 tomwrong부터 일을 계속합니다.이 확장 버전에서는 개체를 두 번 이상 카운트하지 않으므로 무한 루프가 발생하지 않습니다.게다가, 나는 물건의 열쇠도 대략 세어야 한다고 생각한다.
function roughSizeOfObject( value, level ) {
if(level == undefined) level = 0;
var bytes = 0;
if ( typeof value === 'boolean' ) {
bytes = 4;
}
else if ( typeof value === 'string' ) {
bytes = value.length * 2;
}
else if ( typeof value === 'number' ) {
bytes = 8;
}
else if ( typeof value === 'object' ) {
if(value['__visited__']) return 0;
value['__visited__'] = 1;
for( i in value ) {
bytes += i.length * 2;
bytes+= 8; // an assumed existence overhead
bytes+= roughSizeOfObject( value[i], 1 )
}
}
if(level == 0){
clear__visited__(value);
}
return bytes;
}
function clear__visited__(value){
if(typeof value == 'object'){
delete value['__visited__'];
for(var i in value){
clear__visited__(value[i]);
}
}
}
roughSizeOfObject(a);
메모리 감소 노력이 실제로 메모리 감소에 도움이 되는지 알고 싶다.
이 코멘트를 팔로우 하면, 다음과 같이 할 필요가 있습니다.메모리 문제 발생 시도 - 이러한 모든 개체를 생성하고 문제(브라우저 크래시, 브라우저 프리즈 또는 메모리 부족 오류)가 발생할 때까지 상한을 크게 늘리는 코드를 작성합니다.이상적으로는 다른 브라우저와 다른 운영체제를 사용하여 이 실험을 반복해야 합니다.
이제 두 가지 옵션이 있습니다.옵션 1 - 메모리 문제를 생성하지 못했습니다.그래서 당신은 아무 걱정도 안 하고 있지 않습니다.메모리 문제도 없고 프로그램도 정상입니다.
옵션 2 - 메모리 문제가 발생하였습니다.이제 문제가 발생한 제한이 타당한지 자문해 보십시오(즉, 코드를 정상적으로 사용할 때 이 양의 개체가 생성될 가능성이 높습니다).만약 '아니오'라고 대답한다면 당신은 괜찮습니다.그렇지 않으면 코드가 생성할 수 있는 개체 수를 알 수 있습니다.이 제한을 위반하지 않도록 알고리즘을 변경합니다.
라이브러리 【Javascript】sizeof.js
같은 일을 합니다. 넣으세요.
<script type="text/javascript" src="sizeof.js"></script>
size of 함수는 객체를 매개 변수로 사용하여 대략적인 크기를 바이트 단위로 반환합니다.예를 들어 다음과 같습니다.
// define an object
var object =
{
'boolean' : true,
'number' : 1,
'string' : 'a',
'array' : [1, 2, 3]
};
// determine the size of the object
var size = sizeof(object);
함수의 크기는 다른 객체에 대한 여러 참조 및 재귀 참조를 포함하는 객체를 처리할 수 있습니다.
Firefox 확장의 메모리 사용량이 주된 관심사라면 Mozilla 개발자에게 확인해 볼 것을 권장합니다.
Mozilla는 Wiki에서 메모리 누수를 분석하는 도구 목록을 제공합니다.
크롬 현상 도구에는 이러한 기능이 있습니다.저는 이 기사가 매우 유용하다고 느꼈고, 당신이 원하는 대로 바로 할 수 있습니다: https://developers.google.com/chrome-developer-tools/docs/heap-profiling
코드 작업을 해 주신 모든 분들께 감사드립니다!
같은 것을 찾고 있다는 것을 덧붙이고 싶었을 뿐이지만, 제 경우 브라우저에 의해 캐시되었을 수도 있고 아닐 수도 있는 Ajax 호출에서 객체를 재파싱 및 처리할 필요가 없도록 처리되는 객체의 캐시를 관리하기 위한 것입니다.이것은 특히 많은 처리를 필요로 하는 오브젝트(보통 JSON 형식이 아닌 오브젝트)에 도움이 되지만, 이러한 오브젝트를 대규모 프로젝트나 장시간 실행 상태로 두는 어플리케이션/확장에 캐시하는 것은 비용이 많이 들 수 있습니다.
어쨌든, 저는 이것을 다음과 같은 용도로 사용합니다.
var myCache = {
cache: {},
order: [],
size: 0,
maxSize: 2 * 1024 * 1024, // 2mb
add: function(key, object) {
// Otherwise add new object
var size = this.getObjectSize(object);
if (size > this.maxSize) return; // Can't store this object
var total = this.size + size;
// Check for existing entry, as replacing it will free up space
if (typeof(this.cache[key]) !== 'undefined') {
for (var i = 0; i < this.order.length; ++i) {
var entry = this.order[i];
if (entry.key === key) {
total -= entry.size;
this.order.splice(i, 1);
break;
}
}
}
while (total > this.maxSize) {
var entry = this.order.shift();
delete this.cache[entry.key];
total -= entry.size;
}
this.cache[key] = object;
this.order.push({ size: size, key: key });
this.size = total;
},
get: function(key) {
var value = this.cache[key];
if (typeof(value) !== 'undefined') { // Return this key for longer
for (var i = 0; i < this.order.length; ++i) {
var entry = this.order[i];
if (entry.key === key) {
this.order.splice(i, 1);
this.order.push(entry);
break;
}
}
}
return value;
},
getObjectSize: function(object) {
// Code from above estimating functions
},
};
이것은 단순한 예이며 오류가 있을 수 있지만, 어느 정도의 지능으로 정적 객체(콘텐츠는 변경되지 않음)를 유지하는 데 사용할 수 있기 때문에 아이디어를 얻을 수 있습니다.이를 통해 애초에 오브젝트를 생산해야 했던 모든 고가의 처리 요건을 대폭 줄일 수 있습니다.
function sizeOf(parent_data, size)
{
for (var prop in parent_data)
{
let value = parent_data[prop];
if (typeof value === 'boolean')
{
size += 4;
}
else if (typeof value === 'string')
{
size += value.length * 2;
}
else if (typeof value === 'number')
{
size += 8;
}
else
{
let oldSize = size;
size += sizeOf(value, oldSize) - oldSize;
}
}
return size;
}
function roughSizeOfObject(object)
{
let size = 0;
for each (let prop in object)
{
size += sizeOf(prop, 0);
} // for..
return size;
}
Chrome 개발 툴의 타임라인 탭을 사용하여 점점 더 많은 오브젝트를 인스턴스화하여 좋은 견적을 얻을 수 있습니다.다음과 같은 html을 보일러 플레이트로 사용하여 오브젝트의 특성(속성의 수 및 유형 등)을 보다 효과적으로 시뮬레이션할 수 있도록 수정할 수 있습니다.실행 전후에 해당 개발 도구 탭의 맨 아래에 있는 휴지통 비트 아이콘을 클릭할 수 있습니다.
<html>
<script>
var size = 1000*100
window.onload = function() {
document.getElementById("quantifier").value = size
}
function scaffold()
{
console.log("processing Scaffold...");
a = new Array
}
function start()
{
size = document.getElementById("quantifier").value
console.log("Starting... quantifier is " + size);
console.log("starting test")
for (i=0; i<size; i++){
a[i]={"some" : "thing"}
}
console.log("done...")
}
function tearDown()
{
console.log("processing teardown");
a.length=0
}
</script>
<body>
<span style="color:green;">Quantifier:</span>
<input id="quantifier" style="color:green;" type="text"></input>
<button onclick="scaffold()">Scaffold</button>
<button onclick="start()">Start</button>
<button onclick="tearDown()">Clean</button>
<br/>
</body>
</html>
(위의 코드와 같이) 각각 1개의 속성으로 이루어진 200만개의 오브젝트를 인스턴스화하면 현재 내 Chromium에서 오브젝트당 50바이트의 대략적인 계산이 이루어집니다.코드를 변경하여 오브젝트당 임의의 문자열을 생성하면 오브젝트당 약 30바이트가 추가됩니다.이게 도움이 됐으면 좋겠다.
오브젝트의 aprox. size를 프로그램적으로 체크할 필요가 있는 경우는 오브젝트 사이즈에 사용할 수 있었던 라이브러리 http://code.stephenmorley.org/javascript/finding-the-memory-usage-of-objects/도 체크할 수 있습니다.
그렇지 않으면 Chrome/Firefox 힙 프로파일러를 사용할 것을 권장합니다.
위 답변에 문제가 있었습니다.ArrayBuffer
문서를 확인한 결과 ArrayBuffer에는byteLength
필요한 것을 정확하게 알려주는 자산입니다.
function sizeOf(data)
{
if (typeof(data) === 'object')
{
if (data instanceof ArrayBuffer)
{
return data.byteLength;
}
// other objects goes here
}
// non-object cases goes here
}
console.log(sizeOf(new ArrayBuffer(15))); // 15
레퍼런스:
승인된 답변은 와 함께 동작하지 않습니다.Set
,WeakMap
기타 반복할 수 있는 오브젝트.(다른 답변에서 설명한 object-sizeof 패키지에서도 같은 문제가 있습니다).
여기 내 해결책이 있습니다.
export function roughSizeOfObject(object) {
const objectList = [];
const stack = [object];
const bytes = [0];
while (stack.length) {
const value = stack.pop();
if (value == null) bytes[0] += 4;
else if (typeof value === 'boolean') bytes[0] += 4;
else if (typeof value === 'string') bytes[0] += value.length * 2;
else if (typeof value === 'number') bytes[0] += 8;
else if (typeof value === 'object' && objectList.indexOf(value) === -1) {
objectList.push(value);
if (typeof value.byteLength === 'number') bytes[0] += value.byteLength;
else if (value[Symbol.iterator]) {
// eslint-disable-next-line no-restricted-syntax
for (const v of value) stack.push(v);
} else {
Object.keys(value).forEach(k => {
bytes[0] += k.length * 2; stack.push(value[k]);
});
}
}
}
return bytes[0];
}
또, 키 스토리지와 동작하는 키 수 등, 그 외의 사소한 개선도 포함되어 있습니다.ArrayBuffer
.
@Dan의 이미 컴팩트한 솔루션을 기반으로 자체 기능 버전을 소개합니다.콘텍스트를 희생하고 가능한 한 콤팩트하게 하고 싶은 사용자에게는 변수 이름이 한 글자로 축소됩니다.
const ns = {};
ns.sizeof = function(v) {
let f = ns.sizeof, //this needs to match the name of the function itself, since arguments.callee.name is defunct
o = {
"undefined": () => 0,
"boolean": () => 4,
"number": () => 8,
"string": i => 2 * i.length,
"object": i => !i ? 0 : Object
.keys(i)
.reduce((t, k) => f(k) + f(i[k]) + t, 0)
};
return o[typeof v](v);
};
ns.undef;
ns.bool = true;
ns.num = 1;
ns.string = "Hello";
ns.obj = {
first_name: 'John',
last_name: 'Doe',
born: new Date(1980, 1, 1),
favorite_foods: ['Pizza', 'Salad', 'Indian', 'Sushi'],
can_juggle: true
};
console.log(ns.sizeof(ns.undef));
console.log(ns.sizeof(ns.bool));
console.log(ns.sizeof(ns.num));
console.log(ns.sizeof(ns.string));
console.log(ns.sizeof(ns.obj));
console.log(ns.sizeof(ns.obj.favorite_foods));
크롬으로 헤드 스냅샷을 만들고 개체의 크기를 모니터링합니다.
나는 당신이 'array'를 넣는 것을 잊었다고 생각한다.
typeOf : function(value) {
var s = typeof value;
if (s === 'object')
{
if (value)
{
if (typeof value.length === 'number' && !(value.propertyIsEnumerable('length')) && typeof value.splice === 'function')
{
s = 'array';
}
}
else
{
s = 'null';
}
}
return s;
},
estimateSizeOfObject: function(value, level)
{
if(undefined === level)
level = 0;
var bytes = 0;
if ('boolean' === typeOf(value))
bytes = 4;
else if ('string' === typeOf(value))
bytes = value.length * 2;
else if ('number' === typeOf(value))
bytes = 8;
else if ('object' === typeOf(value) || 'array' === typeOf(value))
{
for(var i in value)
{
bytes += i.length * 2;
bytes+= 8; // an assumed existence overhead
bytes+= estimateSizeOfObject(value[i], 1)
}
}
return bytes;
},
formatByteSize : function(bytes)
{
if (bytes < 1024)
return bytes + " bytes";
else
{
var floatNum = bytes/1024;
return floatNum.toFixed(2) + " kb";
}
},
이것이 올바른 방법이 아니라는 것을 알지만, 과거에도 몇 번인가 오브젝트 파일 사이즈를 얻는 데 도움이 되었습니다.
오브젝트/응답 내용을 콘솔 또는 새 탭에 기록하고 결과를 새 메모장 파일에 복사하여 저장한 후 파일 크기를 확인합니다.메모장 파일 자체는 몇 바이트에 불과하기 때문에 꽤 정확한 객체 파일 크기를 얻을 수 있습니다.
언급URL : https://stackoverflow.com/questions/1248302/how-to-get-the-size-of-a-javascript-object
'programing' 카테고리의 다른 글
javascript 파일 이름 짓기 규칙은 무엇입니까? (0) | 2022.10.26 |
---|---|
MySQL에서 Maria로의 이행DB (0) | 2022.10.26 |
Java 문자열의 불변성 (0) | 2022.10.26 |
문자열 "Jun 1 2005 1:33"을 변환합니다.PM"에서 날짜/시간으로 (0) | 2022.10.26 |
Python에서는 어떻게 무한한 수를 표현할 수 있을까요? (0) | 2022.10.26 |