一、前端通过获取Navigator.deviceMemory来查询系统内存。
二、Navigator.deviceMemory
1、navigator_device_memory.idl接口定义:
// https://github.com/w3c/device-memory#the-web-exposed-api
interface mixin NavigatorDeviceMemory {
[HighEntropy=Direct,MeasureAs=NavigatorDeviceMemory,SecureContext]
readonly attribute float deviceMemory;
};
2、v8_navigator
out\Debug\gen\third_party\blink\renderer\bindings\modules\v8\v8_navigator.cc
void DeviceMemoryAttributeGetCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
RUNTIME_CALL_TIMER_SCOPE_DISABLED_BY_DEFAULT(info.GetIsolate(), "Blink_Navigator_deviceMemory_Getter");
BLINK_BINDINGS_TRACE_EVENT("Navigator.deviceMemory.get");
// [HighEntropy]
const Dactyloscoper::HighEntropyTracer high_entropy_tracer("Navigator.deviceMemory.get", info);
v8::Isolate* isolate = info.GetIsolate();
v8::Local<v8::Context> current_context = isolate->GetCurrentContext();
ExecutionContext* current_execution_context = ExecutionContext::From(current_context);
// [Measure], [MeasureAs]
UseCounter::Count(current_execution_context, WebFeature::kNavigatorDeviceMemory);
v8::Local<v8::Object> v8_receiver = info.This();
Navigator* blink_receiver = V8Navigator::ToWrappableUnsafe(isolate, v8_receiver);
auto&& return_value = blink_receiver->deviceMemory();
bindings::V8SetReturnValue(info, return_value, bindings::V8ReturnValue::PrimitiveType<float>());
// [HighEntropy=Direct]
Dactyloscoper::RecordDirectSurface(current_execution_context, WebFeature::kNavigatorDeviceMemory, return_value);
}
3、接口实现c++:
third_party\blink\renderer\core\frame\navigator_device_memory.h
third_party\blink\renderer\core\frame\navigator_device_memory.cc
namespace blink {
float NavigatorDeviceMemory::deviceMemory() const {
return ApproximatedDeviceMemory::GetApproximatedDeviceMemory();
}
} // namespace blink
third_party\blink\common\device_memory\approximated_device_memory.cc
namespace blink {
// static
float ApproximatedDeviceMemory::approximated_device_memory_gb_ = 0.0;
int64_t ApproximatedDeviceMemory::physical_memory_mb_ = 0;
// static
void ApproximatedDeviceMemory::Initialize() {
if (approximated_device_memory_gb_ > 0.0)
return;
DCHECK_EQ(0, physical_memory_mb_);
physical_memory_mb_ = ::base::SysInfo::AmountOfPhysicalMemoryMB();
CalculateAndSetApproximatedDeviceMemory();
}
// static
float ApproximatedDeviceMemory::GetApproximatedDeviceMemory() {
return approximated_device_memory_gb_;
}
// static
void ApproximatedDeviceMemory::CalculateAndSetApproximatedDeviceMemory() {
// The calculations in this method are described in the specification:
// https://w3c.github.io/device-memory/.
DCHECK_GT(physical_memory_mb_, 0);
int lower_bound = physical_memory_mb_;
int power = 0;
// Extract the most-significant-bit and its location.
while (lower_bound > 1) {
lower_bound >>= 1;
power++;
}
// The remaining should always be equal to exactly 1.
DCHECK_EQ(lower_bound, 1);
int64_t upper_bound = lower_bound + 1;
lower_bound = lower_bound << power;
upper_bound = upper_bound << power;
// Find the closest bound, and convert it to GB.
if (physical_memory_mb_ - lower_bound <= upper_bound - physical_memory_mb_)
approximated_device_memory_gb_ = static_cast<float>(lower_bound) / 1024.0;
else
approximated_device_memory_gb_ = static_cast<float>(upper_bound) / 1024.0;
// Max-limit the reported value to 8GB to reduce fingerprintability of
// high-spec machines.
if (approximated_device_memory_gb_ > 8)
approximated_device_memory_gb_ = 8.0;
}
// static
void ApproximatedDeviceMemory::SetPhysicalMemoryMBForTesting(
int64_t physical_memory_mb) {
physical_memory_mb_ = physical_memory_mb;
CalculateAndSetApproximatedDeviceMemory();
}
} // namespace blink
三、调用堆栈:
Navigator.deviceMemory 调用c++NavigatorDeviceMemory::deviceMemory()接口 返回内存大小指纹。
注意:当系统内存大于8GB时候浏览器默认是8G
四、总结:
修改内存指纹只需要在NavigatorDeviceMemory::deviceMemory()函数里面修改即可。
五、看下效果:
本人机器64G内存,浏览器默认指纹显示8G,将其改为18G编译看下效果。