JavaScript 객체의 크기를 얻는 방법?
JavaScript 객체가 차지하는 크기를 알고 싶습니다.
다음 기능을 수행하십시오.
function Marks(){
this.maxMarks = 100;
}
function Student(){
this.firstName = "firstName";
this.lastName = "lastName";
this.marks = new Marks();
}
이제 다음을 인스턴스화합니다 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;
}
Chrome 힙 프로파일 러를 사용하면 객체 메모리 사용을 검사 할 수 있습니다.
까다로울 수있는 추적에서 개체를 찾을 수 있어야합니다. 객체를 Window 전역에 고정하면 "컨테이너"목록 모드에서 쉽게 찾을 수 있습니다.
첨부 된 스크린 샷에서 창에 "testObj"라는 객체를 만들었습니다. 그런 다음 프로파일 러에 위치하여 (기록한 후) 개체의 전체 크기와 "보존 크기"아래의 모든 개체를 보여줍니다.
위의 스크린 샷에서 객체의 크기는 60으로 유지됩니다. 단위는 바이트라고 생각합니다.
방금 비슷한 (ish) 문제를 해결하기 위해 이것을 썼습니다. 그것은 당신이 찾고있는 것을 정확하게하지 않습니다. 즉, 인터프리터가 객체를 저장하는 방법을 고려하지 않습니다.
그러나 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;
이 객체를 sizeof를 얻을 수 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));
파티에 조금 늦었지만 여기에 약간 더 컴팩트 한 해결책이 있습니다.
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);
이것은 해키 방법이지만 다른 숫자로 두 번 시도했지만 일관된 것처럼 보입니다.
당신이 할 수있는 일은 원하는 종류의 1 ~ 2 백만 개의 객체와 같은 엄청난 수의 객체를 할당하고 할당하는 것입니다. 가비지 수집기에서 객체를 해제하지 못하게하기 위해 객체를 배열에 넣습니다 (배열로 인해 약간의 메모리 오버 헤드가 추가되지만 메모리에있는 객체에 대해 걱정할 경우 문제가되지 않기를 바랍니다) , 당신은 어딘가에 그들을 저장) 할당 전후에 경고를 추가하고 각 경고에서 Firefox 프로세스가 얼마나 많은 메모리를 사용하는지 확인하십시오. 테스트를 통해 페이지를 열기 전에 새 Firefox 인스턴스가 있는지 확인하십시오. 페이지를 열고 "이전"경고가 표시된 후 메모리 사용량을 확인하십시오. 경고를 닫고 메모리가 할당 될 때까지 기다리십시오. 오래된 메모리에서 새 메모리를 빼고 할당량으로 나눕니다.
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');
컴퓨터에서이 작업을 시도했는데 "이전"경고가 표시 될 때 프로세스에 48352K의 메모리가있었습니다. 할당 후 Firefox에는 440236K의 메모리가있었습니다. 200 만 할당의 경우 각 개체 당 약 200 바이트입니다.
나는 1million 할당으로 다시 시도했고 결과는 비슷했습니다 : 객체 당 196 바이트 (2mill의 여분의 데이터가 Array에 사용되었다고 가정).
따라서 여기 도움이 될만한 해키 방법이 있습니다. JavaScript는 "sizeof"메소드를 제공하지 않습니다. 각 JavaScript 구현은 다릅니다. 예를 들어 Chrome에서 동일한 페이지는 각 객체에 대해 약 66 바이트를 사용합니다 (적어도 작업 관리자에서 판단).
댓글을 달 수 없어 죄송합니다. 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);
같은 문제가 있습니다. Google에서 검색 했으며이 솔루션을 stackoverflow 커뮤니티와 공유하고 싶습니다.
중요 :
github에서 Yan Qing이 공유 한 기능을 사용했습니다 https://gist.github.com/zensh/4975495
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);
당신이 그것에 대해 어떻게 생각하십니까?
내 메모리 감소 노력이 실제로 메모리 감소에 도움이되는지 알고 싶습니다.
이 주석에 이어 수행해야 할 작업은 다음과 같습니다. 메모리 문제 생성-이러한 모든 개체를 생성하고 문제가 발생할 때까지 (브라우저 충돌, 브라우저 정지 또는 Out-Of- 메모리 오류). 이상적으로는 다른 브라우저와 다른 운영 체제에서이 실험을 반복해야합니다.
이제 두 가지 옵션이 있습니다. 옵션 1-메모리 문제를 생성하지 못했습니다. 그러므로 당신은 아무것도 걱정하지 않습니다. 메모리 문제가 없으며 프로그램이 정상입니다.
옵션 2- 메모리 문제가 발생했습니다. 이제 문제가 발생한 한계가 합리적인지 자문 해보십시오 (즉, 코드를 정상적으로 사용할 때이 정도의 객체가 생성 될 가능성이 있습니까). 대답이 '아니요'이면 괜찮습니다. 그렇지 않으면 이제 코드에서 만들 수있는 객체 수를 알 수 있습니다. 알고리즘이이 한계를 초과하지 않도록 재 작업하십시오.
이 Javascript 라이브러리 sizeof.js
는 동일한 작업을 수행합니다. 이렇게 포함 시키십시오
<script type="text/javascript" src="sizeof.js"></script>
sizeof 함수는 객체를 매개 변수로 사용하여 대략적인 크기 (바이트)를 반환합니다. 예를 들면 다음과 같습니다.
// 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);
sizeof 함수는 다른 객체에 대한 다중 참조와 재귀 참조를 포함하는 객체를 처리 할 수 있습니다.
Firefox 확장 프로그램의 메모리 사용량이 주요 관심사 인 경우 Mozilla 개발자에게 문의하십시오.
Mozilla는 위키에서 메모리 누수를 분석하는 도구 목록을 제공합니다 .
Chrome 개발자 도구에는이 기능이 있습니다. 이 도움말이 매우 도움이되었고 원하는 내용을 정확하게 수행했습니다. https://developers.google.com/chrome-developer-tools/docs/heap-profiling
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;
}
이를 위해 코드 작업을 해주신 모든 분들께 감사드립니다!
나는 정확히 똑같은 것을 찾고 있다고 덧붙이고 싶지만 내 경우에는 캐시되었거나 캐시되지 않은 아약스 호출에서 객체를 다시 구문 분석하고 처리하지 않도록 처리 된 객체의 캐시를 관리하기위한 것입니다. 브라우저에서. 이것은 많은 처리가 필요한 객체, 일반적으로 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
},
};
간단한 예제이며 약간의 오류가있을 수 있지만 어느 정도의 지능으로 정적 개체 (내용은 변경되지 않음)를 유지하는 데 사용할 수 있으므로 아이디어를 제공합니다. 이를 통해 처음에 객체를 생산해야하는 고가의 처리 요구 사항을 크게 줄일 수 있습니다.
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>
위의 코드에서와 같이 각각 하나의 속성으로 2 백만 개의 객체를 인스턴스화하면 현재 Chromium에서 객체 당 대략 50 바이트의 계산이 이루어집니다. 객체 당 임의의 문자열을 생성하도록 코드를 변경하면 객체 당 약 30 바이트가 추가됩니다. 이것이 도움이 되길 바랍니다.
프로그래밍 방식으로 aprox를 확인해야하는 경우 객체의 크기 객체 크기에 사용할 수있는 이 라이브러리 http://code.stephenmorley.org/javascript/finding-the-memory-usage-of-objects/ 를 확인할 수도 있습니다 .
그렇지 않으면 Chrome / Firefox 힙 프로파일 러를 사용하는 것이 좋습니다.
나는 당신이 '배열'을 포함하는 것을 잊었다 고 생각합니다.
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";
}
},
내가 아는 이 절대적으로 옳은 방법이 아니다, 그러나 it've는 약 오브젝트 파일의 크기를 얻을 수있는 과거에 나에게 몇 번 도움 :
콘솔 또는 새 탭에 개체 / 응답을 쓰고 결과를 새 메모장 파일로 복사 한 후 저장하고 파일 크기를 확인하십시오. 메모장 파일 자체는 단지 몇 바이트이므로 상당히 정확한 객체 파일 크기를 얻을 수 있습니다.
참고 URL : https://stackoverflow.com/questions/1248302/how-to-get-the-size-of-a-javascript-object
'Programing' 카테고리의 다른 글
RuntimeWarning : DateTimeField가 순진한 datetime을 받았습니다 (0) | 2020.03.31 |
---|---|
두 응용 프로그램이 동일한 포트를 수신 할 수 있습니까? (0) | 2020.03.31 |
병합되지 않은 Git 브랜치를 찾으십니까? (0) | 2020.03.31 |
해시 마크 (#)로 git commit 메시지를 시작하십시오 (0) | 2020.03.31 |
Moq에서 out / ref 파라미터 지정 (0) | 2020.03.31 |